xref: /rockchip-linux_mpp/mpp/vproc/iep/iep.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3  * Copyright (c) 2018 Rockchip Electronics Co., Ltd.
4  */
5 
6 #define MODULE_TAG "iep"
7 
8 #include <math.h>
9 #include <string.h>
10 
11 #include "mpp_env.h"
12 #include "mpp_mem.h"
13 #include "mpp_debug.h"
14 #include "mpp_common.h"
15 
16 #include "iep_api.h"
17 #include "iep.h"
18 
19 #define X   (-1)
20 
21 static RK_S32 enh_alpha_table[][25] = {
22     //      0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20  21  22  23  24
23     /*0*/  {X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X },
24     /*1*/  {0,  8, 12, 16, 20, 24, 28,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X },
25     /*2*/  {0,  4,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  X },
26     /*3*/  {0,  X,  X,  8,  X,  X, 12,  X,  X, 16,  X,  X, 20,  X,  X, 24,  X,  X, 28,  X,  X,  X,  X,  X,  X },
27     /*4*/  {0,  2,  4,  6,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 },
28     /*5*/  {0,  X,  X,  X,  X,  8,  X,  X,  X,  X, 12,  X,  X,  X,  X, 16,  X,  X,  X,  X, 20,  X,  X,  X,  X },
29     /*6*/  {0,  X,  X,  4,  X,  X,  8,  X,  X, 10,  X,  X, 12,  X,  X, 14,  X,  X, 16,  X,  X, 18,  X,  X, 20 },
30     /*7*/  {0,  X,  X,  X,  X,  X,  X,  8,  X,  X,  X,  X,  X,  X, 12,  X,  X,  X,  X,  X,  X, 16,  X,  X,  X },
31     /*8*/  {0,  1,  2,  3,  4,  5,  6,  7,  8,  X,  9,  X, 10,  X, 11,  X, 12,  X, 13,  X, 14,  X,  15, X, 16 }
32 };
33 
34 static const char *iep_name = "/dev/iep";
35 
36 typedef struct IepCtxImpl_t {
37     IepMsg      msg;
38     RK_S32      fd;
39     RK_S32      pid;
40     IepHwCap    cap;
41 } IepCtxImpl;
42 
iep_init(IepCtx * ctx)43 MPP_RET iep_init(IepCtx *ctx)
44 {
45     if (NULL == ctx) {
46         mpp_err_f("invalid NULL input\n");
47         return MPP_ERR_NULL_PTR;
48     }
49 
50     RK_S32 fd = -1;
51     IepCtxImpl *impl = NULL;
52 
53     mpp_env_get_u32("iep_debug", &iep_debug, 0);
54     *ctx = NULL;
55 
56     do {
57         impl = mpp_calloc(IepCtxImpl, 1);
58         if (NULL == impl) {
59             mpp_err_f("failed to alloc context\n");
60             break;
61         }
62 
63         fd = open(iep_name, O_RDWR | O_CLOEXEC);
64         if (fd < 0) {
65             mpp_err("can NOT find iep device %s\n", iep_name);
66             break;
67         }
68 
69         if (0 > ioctl(fd, IEP_QUERY_CAP, &impl->cap)) {
70             iep_dbg_func("Query IEP capability failed, using default cap\n");
71             IepHwCap *cap = &impl->cap;
72 
73             cap->scaling_supported = 0;
74             cap->i4_deinterlace_supported = 1;
75             cap->i2_deinterlace_supported = 1;
76             cap->compression_noise_reduction_supported = 1;
77             cap->sampling_noise_reduction_supported = 1;
78             cap->hsb_enhancement_supported = 1;
79             cap->cg_enhancement_supported = 1;
80             cap->direct_path_supported = 1;
81             cap->max_dynamic_width = 1920;
82             cap->max_dynamic_height = 1088;
83             cap->max_static_width = 8192;
84             cap->max_static_height = 8192;
85             cap->max_enhance_radius = 3;
86         }
87 
88         impl->fd = fd;
89         impl->pid = getpid();
90 
91         *ctx = impl;
92         return MPP_OK;
93     } while (0);
94 
95     if (fd > 0)
96         close(fd);
97 
98     MPP_FREE(impl);
99 
100     return MPP_NOK;
101 }
102 
iep_deinit(IepCtx ctx)103 MPP_RET iep_deinit(IepCtx ctx)
104 {
105     if (NULL == ctx) {
106         mpp_err_f("invalid NULL input\n");
107         return MPP_ERR_NULL_PTR;
108     }
109 
110     IepCtxImpl *impl = (IepCtxImpl *)ctx;
111 
112     if (impl->fd > 0) {
113         close(impl->fd);
114         impl->fd = -1;
115     }
116 
117     return MPP_OK;
118 }
119 
dump_iep_img(IepImg * img)120 static void dump_iep_img(IepImg *img)
121 {
122     mpp_log("image    %p\n", img);
123     mpp_log("act_w    %d\n", img->act_w);
124     mpp_log("act_h    %d\n", img->act_h);
125     mpp_log("x_off    %d\n", img->x_off);
126     mpp_log("y_off    %d\n", img->y_off);
127     mpp_log("vir_w    %d\n", img->vir_w);
128     mpp_log("vir_h    %d\n", img->vir_h);
129     mpp_log("format   %d\n", img->format);
130     mpp_log("mem_addr %08x\n", img->mem_addr);
131     mpp_log("uv_addr  %08x\n", img->uv_addr);
132     mpp_log("v_addr   %08x\n", img->v_addr);
133 }
134 
check_yuv_enhance_param(IepCmdParamYuvEnhance * yuv_enh)135 static RK_U32 check_yuv_enhance_param(IepCmdParamYuvEnhance *yuv_enh)
136 {
137     RK_U32 ret = 0;
138     if (yuv_enh->saturation < 0 || yuv_enh->saturation > 1.992) {
139         mpp_err("Invalidate parameter, yuv_enh_saturation!\n");
140         ret |= 0x0001;
141     }
142 
143     if (yuv_enh->contrast < 0 || yuv_enh->contrast > 1.992) {
144         mpp_err("Invalidate parameter, yuv_enh_contrast!\n");
145         ret |= 0x0002;
146     }
147 
148     if (yuv_enh->brightness < -32 || yuv_enh->brightness > 31) {
149         mpp_err("Invalidate parameter, yuv_enh_brightness!\n");
150         ret |= 0x0004;
151     }
152 
153     if (yuv_enh->hue_angle < -30 || yuv_enh->hue_angle > 30) {
154         mpp_err("Invalidate parameter, yuv_enh_hue_angle!\n");
155         ret |= 0x0008;
156     }
157 
158     if (yuv_enh->video_mode < 0 || yuv_enh->video_mode > 3) {
159         mpp_err("Invalidate parameter, video_mode!\n");
160         ret |= 0x0010;
161     }
162 
163     if (yuv_enh->color_bar_y > 127 || yuv_enh->color_bar_u > 127 ||
164         yuv_enh->color_bar_v > 127) {
165         mpp_err("Invalidate parameter, color_bar_*!\n");
166         ret |= 0x0020;
167     }
168     return ret;
169 }
170 
check_rgb_enhance_param(IepCmdParamRgbEnhance * rgb_enh)171 static RK_U32 check_rgb_enhance_param(IepCmdParamRgbEnhance *rgb_enh)
172 {
173     RK_U32 ret = 0;
174     if (rgb_enh->alpha_base > 8 || rgb_enh->alpha_base < 0 ||
175         rgb_enh->alpha_num  < 0 || rgb_enh->alpha_num  > 24) {
176         mpp_err("Invalidate parameter, enh_alpha_base or enh_alpha_num!\n");
177         ret |= 0x0001;
178     }
179 
180     if (enh_alpha_table[rgb_enh->alpha_base][rgb_enh->alpha_num] == -1) {
181         mpp_err("Invalidate parameter, enh_alpha_base or enh_alpha_num!\n");
182         ret |= 0x0002;
183     }
184 
185     if (rgb_enh->threshold > 255 || rgb_enh->threshold < 0) {
186         mpp_err("Invalidate parameter, enh_threshold!\n");
187         ret |= 0x0004;
188     }
189 
190     if (rgb_enh->radius > 4 || rgb_enh->radius < 1) {
191         mpp_err("Invalidate parameter, enh_radius!\n");
192         ret |= 0x0008;
193     }
194 
195     if (rgb_enh->order < IEP_RGB_ENHANCE_ORDER_CG_DDE ||
196         rgb_enh->order > IEP_RGB_ENHANCE_ORDER_DDE_CG) {
197         mpp_err("Invalidate parameter, rgb_contrast_enhance_mode!\n");
198         ret |= 0x0010;
199     }
200 
201     if (rgb_enh->mode < IEP_RGB_ENHANCE_MODE_NO_OPERATION ||
202         rgb_enh->mode > IEP_RGB_ENHANCE_MODE_EDGE_ENHANCE) {
203         mpp_err("Invalidate parameter, rgb_enhance_mode!\n");
204         ret |= 0x0020;
205     }
206 
207     if (rgb_enh->coe > 3.96875 || rgb_enh->coe < 0) {
208         mpp_err("Invalidate parameter, rgb_enh_coe!\n");
209         ret |= 0x0040;
210     }
211 
212     return ret;
213 }
214 
check_msg_image(IepMsg * msg)215 static RK_U32 check_msg_image(IepMsg *msg)
216 {
217     RK_U32 ret = 0;
218     IepMsgImg *src = &msg->src;
219     IepMsgImg *dst = &msg->dst;
220 
221     if (!((src->format < IEP_FORMAT_RGB_BUTT) ||
222           (src->format >= IEP_FORMAT_YUV_BASE && src->format < IEP_FORMAT_YUV_BUTT))) {
223         mpp_err("Invalidate parameter, i/o format!\n");
224         ret |= 0x0001;
225     }
226 
227     if (src->act_w > 4096 || src->act_h > 8192) {
228         mpp_err("Invalidate parameter, source image size!\n");
229         ret |= 0x0002;
230     }
231 
232     if (dst->act_w > 4096 || dst->act_h > 4096) {
233         mpp_err("Invalidate parameter, destination image size!\n");
234         ret |= 0x0004;
235     }
236 
237     RK_S32 scl_fct_h = src->act_w > dst->act_w ? (src->act_w * 1000 / dst->act_w) : (dst->act_w * 1000 / src->act_w);
238     RK_S32 scl_fct_v = src->act_h > dst->act_h ? (src->act_h * 1000 / dst->act_h) : (dst->act_h * 1000 / src->act_h);
239 
240     if (scl_fct_h > 16000 || scl_fct_v > 16000) {
241         mpp_err("Invalidate parameter, scale factor!\n");
242         ret |= 0x0008;
243     }
244     return ret;
245 }
246 
247 // rr = 1.7 rg = 1 rb = 0.6
248 static RK_U32 cg_tab[] = {
249     0x01010100, 0x03020202, 0x04030303, 0x05040404,
250     0x05050505, 0x06060606, 0x07070606, 0x07070707,
251     0x08080807, 0x09080808, 0x09090909, 0x0a090909,
252     0x0a0a0a0a, 0x0b0a0a0a, 0x0b0b0b0b, 0x0c0b0b0b,
253     0x0c0c0c0c, 0x0c0c0c0c, 0x0d0d0d0d, 0x0d0d0d0d,
254     0x0e0e0d0d, 0x0e0e0e0e, 0x0e0e0e0e, 0x0f0f0f0f,
255     0x0f0f0f0f, 0x10100f0f, 0x10101010, 0x10101010,
256     0x11111110, 0x11111111, 0x11111111, 0x12121212,
257     0x12121212, 0x12121212, 0x13131313, 0x13131313,
258     0x13131313, 0x14141414, 0x14141414, 0x14141414,
259     0x15151515, 0x15151515, 0x15151515, 0x16161615,
260     0x16161616, 0x16161616, 0x17161616, 0x17171717,
261     0x17171717, 0x17171717, 0x18181818, 0x18181818,
262     0x18181818, 0x19191818, 0x19191919, 0x19191919,
263     0x19191919, 0x1a1a1a19, 0x1a1a1a1a, 0x1a1a1a1a,
264     0x1a1a1a1a, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
265     0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
266     0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,
267     0x23222120, 0x27262524, 0x2b2a2928, 0x2f2e2d2c,
268     0x33323130, 0x37363534, 0x3b3a3938, 0x3f3e3d3c,
269     0x43424140, 0x47464544, 0x4b4a4948, 0x4f4e4d4c,
270     0x53525150, 0x57565554, 0x5b5a5958, 0x5f5e5d5c,
271     0x63626160, 0x67666564, 0x6b6a6968, 0x6f6e6d6c,
272     0x73727170, 0x77767574, 0x7b7a7978, 0x7f7e7d7c,
273     0x83828180, 0x87868584, 0x8b8a8988, 0x8f8e8d8c,
274     0x93929190, 0x97969594, 0x9b9a9998, 0x9f9e9d9c,
275     0xa3a2a1a0, 0xa7a6a5a4, 0xabaaa9a8, 0xafaeadac,
276     0xb3b2b1b0, 0xb7b6b5b4, 0xbbbab9b8, 0xbfbebdbc,
277     0xc3c2c1c0, 0xc7c6c5c4, 0xcbcac9c8, 0xcfcecdcc,
278     0xd3d2d1d0, 0xd7d6d5d4, 0xdbdad9d8, 0xdfdedddc,
279     0xe3e2e1e0, 0xe7e6e5e4, 0xebeae9e8, 0xefeeedec,
280     0xf3f2f1f0, 0xf7f6f5f4, 0xfbfaf9f8, 0xfffefdfc,
281     0x06030100, 0x1b150f0a, 0x3a322922, 0x63584e44,
282     0x95887b6f, 0xcebfb0a2, 0xfffeedde, 0xffffffff,
283     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
284     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
285     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
286     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
287     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
288     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
289     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
290     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
291     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
292     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
293     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
294     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
295     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
296     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
297 };
298 
setup_cg_tab(double cg_rate,RK_U32 * base)299 static void setup_cg_tab(double cg_rate, RK_U32 *base)
300 {
301     RK_S32 i;
302 
303     for (i = 0; i < 64; i++) {
304         RK_U32 rgb_0 = 4 * i;
305         RK_U32 rgb_1 = 4 * i + 1;
306         RK_U32 rgb_2 = 4 * i + 2;
307         RK_U32 rgb_3 = 4 * i + 3;
308 
309         /// need modify later
310         RK_U32 cg_0 = pow(rgb_0, cg_rate);
311         RK_U32 cg_1 = pow(rgb_1, cg_rate);
312         RK_U32 cg_2 = pow(rgb_2, cg_rate);
313         RK_U32 cg_3 = pow(rgb_3, cg_rate);
314 
315         if (cg_0 > 255) cg_0 = 255;
316         if (cg_1 > 255) cg_1 = 255;
317         if (cg_2 > 255) cg_2 = 255;
318         if (cg_3 > 255) cg_3 = 255;
319 
320         RK_U32 tab_0 = (RK_U32)cg_0;
321         RK_U32 tab_1 = (RK_U32)cg_1;
322         RK_U32 tab_2 = (RK_U32)cg_2;
323         RK_U32 tab_3 = (RK_U32)cg_3;
324 
325         RK_U32 conf_value = (tab_3 << 24) + (tab_2 << 16) + (tab_1 << 8) + tab_0;
326         base[i] = conf_value;
327     }
328 }
329 
iep_control(IepCtx ctx,IepCmd cmd,void * param)330 MPP_RET iep_control(IepCtx ctx, IepCmd cmd, void *param)
331 {
332     if (NULL == ctx) {
333         mpp_err_f("invalid NULL input\n");
334         return MPP_ERR_NULL_PTR;
335     }
336 
337     MPP_RET ret = MPP_OK;
338     IepCtxImpl *impl = (IepCtxImpl *)ctx;
339     IepMsg *msg = &impl->msg;
340 
341     switch (cmd) {
342     case IEP_CMD_INIT : {
343         memset(msg, 0, sizeof(*msg));
344     } break;
345     case IEP_CMD_SET_SRC : {
346         IepMsgImg *src = &msg->src;
347 
348         mpp_assert(param);
349         // NOTE: only update which is used
350         memcpy(&msg->src, param, sizeof(IepImg));
351 
352         if ((src->format == IEP_FORMAT_YCbCr_420_P
353              || src->format == IEP_FORMAT_YCbCr_420_SP
354              || src->format == IEP_FORMAT_YCbCr_422_P
355              || src->format == IEP_FORMAT_YCbCr_422_SP
356              || src->format == IEP_FORMAT_YCrCb_420_P
357              || src->format == IEP_FORMAT_YCrCb_420_SP
358              || src->format == IEP_FORMAT_YCrCb_422_P
359              || src->format == IEP_FORMAT_YCrCb_422_SP) &&
360             msg->dein_mode == IEP_DEI_MODE_DISABLE) {
361             msg->dein_mode = IEP_DEI_MODE_BYPASS;
362         }
363         if (iep_debug & IEP_DBG_IMAGE) {
364             mpp_log("setup src\n");
365             dump_iep_img((IepImg *)param);
366         }
367     } break;
368     case IEP_CMD_SET_DST : {
369         mpp_assert(param);
370         // NOTE: only update which is used
371         memcpy(&msg->dst, param, sizeof(IepImg));
372 
373         if (iep_debug & IEP_DBG_IMAGE) {
374             mpp_log("setup dst\n");
375             dump_iep_img((IepImg *)param);
376         }
377     } break;
378     case IEP_CMD_SET_DEI_CFG : {
379         IepCmdParamDeiCfg *dei_cfg = (IepCmdParamDeiCfg *)param;
380 
381         if (NULL == param) {
382             msg->dein_high_fre_en   = 0;
383             msg->dein_mode          = IEP_DEI_MODE_I2O1;
384             msg->field_order        = IEP_DEI_FLD_ORDER_BOT_FIRST;
385             msg->dein_ei_mode       = 0;
386             msg->dein_ei_sel        = 0;
387             msg->dein_ei_radius     = 0;
388             msg->dein_ei_smooth     = 0;
389             msg->dein_high_fre_fct  = 0;
390         } else {
391             msg->dein_high_fre_en   = dei_cfg->dei_high_freq_en;
392             msg->dein_mode          = dei_cfg->dei_mode;
393             msg->field_order        = dei_cfg->dei_field_order;
394             msg->dein_ei_mode       = dei_cfg->dei_ei_mode;
395             msg->dein_ei_sel        = dei_cfg->dei_ei_sel;
396             msg->dein_ei_radius     = dei_cfg->dei_ei_radius;
397             msg->dein_ei_smooth     = dei_cfg->dei_ei_smooth;
398             msg->dein_high_fre_fct  = dei_cfg->dei_high_freq_fct;
399         }
400         switch (msg->dein_mode) {
401         case IEP_DEI_MODE_DISABLE : {
402             msg->dein_mode = IEP_DEI_MODE_BYPASS;
403         } break;
404         case IEP_DEI_MODE_I2O1 :
405         case IEP_DEI_MODE_I4O1 :
406         case IEP_DEI_MODE_I4O2 : {
407             // for avoid hardware error we need to config src1 and dst1
408             if (!msg->src1.mem_addr)
409                 memcpy(&msg->src1, &msg->src, sizeof(msg->src));
410             if (!msg->dst1.mem_addr)
411                 memcpy(&msg->dst1, &msg->dst, sizeof(msg->dst));
412         } break;
413         default : {
414         } break;
415         }
416     } break;
417     case IEP_CMD_SET_DEI_SRC1 : {
418         mpp_assert(param);
419         // NOTE: only update which is used
420         memcpy(&msg->src1, param, sizeof(IepImg));
421         if (iep_debug & IEP_DBG_IMAGE) {
422             mpp_log("setup src1\n");
423             dump_iep_img((IepImg *)param);
424         }
425     } break;
426     case IEP_CMD_SET_DEI_DST1 : {
427         mpp_assert(param);
428         // NOTE: only update which is used
429         memcpy(&msg->dst1, param, sizeof(IepImg));
430         if (iep_debug & IEP_DBG_IMAGE) {
431             mpp_log("setup dst1\n");
432             dump_iep_img((IepImg *)param);
433         }
434     } break;
435     case IEP_CMD_SET_YUV_ENHANCE : {
436         IepCmdParamYuvEnhance *yuv_enh = (IepCmdParamYuvEnhance *)param;
437 
438         if (NULL == yuv_enh) {
439             msg->yuv_enhance_en = 1;
440 
441             msg->sat_con_int = 0x80;
442             msg->contrast_int = 0x80;
443             // hue_angle = 0
444             msg->cos_hue_int = 0x00;
445             msg->sin_hue_int = 0x80;
446 
447             msg->yuv_enh_brightness = 0x00;
448 
449             msg->video_mode = IEP_VIDEO_MODE_NORMAL_VIDEO;
450 
451             msg->color_bar_u = 0;
452             msg->color_bar_v = 0;
453             msg->color_bar_y = 0;
454             break;
455         }
456 
457         if (check_yuv_enhance_param(yuv_enh)) {
458             ret = MPP_NOK;
459             break;
460         }
461 
462         if (msg->src.format >= 1 && msg->src.format <= 5 &&
463             msg->dst.format >= 1 && msg->dst.format <= 5) {
464             mpp_err("Invalidate parameter, contradition between in/out format and yuv enhance\n");
465             ret = MPP_NOK;
466             break;
467         }
468 
469         msg->yuv_enhance_en = 1;
470 
471         msg->sat_con_int = (RK_S32)(yuv_enh->saturation * yuv_enh->contrast * 128);
472         msg->contrast_int = (RK_S32)(yuv_enh->contrast * 128);
473         msg->cos_hue_int = (RK_S32)(cos(yuv_enh->hue_angle) * 128.0);
474         msg->sin_hue_int = (RK_S32)(sin(yuv_enh->hue_angle) * 128.0);
475         msg->yuv_enh_brightness = yuv_enh->brightness >= 0 ?
476                                   yuv_enh->brightness :
477                                   (yuv_enh->brightness + 64);
478 
479         msg->video_mode  = yuv_enh->video_mode;
480         msg->color_bar_y = yuv_enh->color_bar_y;
481         msg->color_bar_u = yuv_enh->color_bar_u;
482         msg->color_bar_v = yuv_enh->color_bar_v;
483     } break;
484     case IEP_CMD_SET_RGB_ENHANCE : {
485         RK_U32 i;
486         IepCmdParamRgbEnhance *rgb_enh = (IepCmdParamRgbEnhance *)param;
487 
488         if (NULL == rgb_enh) {
489             msg->rgb_color_enhance_en       = 1;
490             msg->rgb_enh_coe                = 32;
491             msg->rgb_contrast_enhance_mode  = IEP_RGB_ENHANCE_MODE_DETAIL_ENHANCE;
492             msg->rgb_cg_en                  = 0;
493             msg->enh_threshold              = 255;
494             msg->enh_alpha                  = 8;
495             msg->enh_radius                 = 3;
496 
497             for (i = 0; i < MPP_ARRAY_ELEMS(cg_tab); i++)
498                 msg->cg_tab[i] = cg_tab[i];
499 
500             break;
501         }
502 
503         if (check_rgb_enhance_param(rgb_enh)) {
504             ret = MPP_NOK;
505             break;
506         }
507 
508         if ((msg->src.format & IEP_FORMAT_YUV_BASE) &&
509             (msg->dst.format & IEP_FORMAT_YUV_BASE)) {
510             mpp_err("Invalidate parameter, contradition between in/out format and yuv enhance\n");
511             ret = MPP_NOK;
512             break;
513         }
514 
515         msg->rgb_color_enhance_en       = 1;
516         msg->rgb_enh_coe                = (RK_U32)(rgb_enh->coe * 32);
517         msg->rgb_contrast_enhance_mode  = rgb_enh->order;
518         msg->rgb_cg_en                  = rgb_enh->cg_en;
519         msg->rgb_enhance_mode           = rgb_enh->mode;
520 
521         msg->enh_threshold = rgb_enh->threshold;
522         msg->enh_alpha     =
523             enh_alpha_table[rgb_enh->alpha_base][rgb_enh->alpha_num];
524         msg->enh_radius    = rgb_enh->radius - 1;
525 
526         if (rgb_enh->cg_en) {
527             setup_cg_tab(rgb_enh->cg_rb, msg->cg_tab);
528             setup_cg_tab(rgb_enh->cg_rg, msg->cg_tab + 64);
529             setup_cg_tab(rgb_enh->cg_rb, msg->cg_tab + 128);
530         }
531     } break;
532     case IEP_CMD_SET_SCALE : {
533         IepCmdParamScale *scale = (IepCmdParamScale *)param;
534 
535         msg->scale_up_mode = (scale) ? (scale->scale_alg) : (IEP_SCALE_ALG_CATROM);
536     } break;
537     case IEP_CMD_SET_COLOR_CONVERT : {
538         IepCmdParamColorConvert *color_cvt = (IepCmdParamColorConvert *)param;
539 
540         if (NULL == color_cvt) {
541             msg->rgb2yuv_mode       = IEP_COLOR_MODE_BT601_L;
542             msg->yuv2rgb_mode       = IEP_COLOR_MODE_BT601_L;
543             msg->rgb2yuv_clip_en    = 0;
544             msg->yuv2rgb_clip_en    = 0;
545             msg->global_alpha_value = 0;
546             msg->dither_up_en       = 1;
547             msg->dither_down_en     = 1;
548             break;
549         }
550 
551         if (color_cvt->dither_up_en && msg->src.format != IEP_FORMAT_RGB_565) {
552             mpp_err("Invalidate parameter, contradiction between dither up enable and source image format!\n");
553             ret = MPP_NOK;
554             break;
555         }
556 
557         if (color_cvt->dither_down_en && msg->dst.format != IEP_FORMAT_RGB_565) {
558             mpp_err("Invalidate parameter, contradiction between dither down enable and destination image format!\n");
559             ret = MPP_NOK;
560             break;
561         }
562 
563         msg->rgb2yuv_mode       = color_cvt->rgb2yuv_mode;
564         msg->yuv2rgb_mode       = color_cvt->yuv2rgb_mode;
565         msg->rgb2yuv_clip_en    = color_cvt->rgb2yuv_input_clip;
566         msg->yuv2rgb_clip_en    = color_cvt->yuv2rgb_input_clip;
567         msg->global_alpha_value = color_cvt->global_alpha_value;
568         msg->dither_up_en       = color_cvt->dither_up_en;
569         msg->dither_down_en     = color_cvt->dither_down_en;
570     } break;
571     case IEP_CMD_RUN_SYNC : {
572         check_msg_image(msg);
573 
574         int ops_ret = ioctl(impl->fd, IEP_SET_PARAMETER, msg);
575         if (ops_ret < 0)
576             mpp_err("pid %d ioctl IEP_SET_PARAMETER failure\n", impl->pid);
577 
578         // NOTE: force result sync to avoid iep task queue full
579         ops_ret = ioctl(impl->fd, IEP_GET_RESULT_SYNC, 0);
580         if (ops_ret)
581             mpp_err("pid %d get result failure\n", impl->pid);
582 
583         ret = (MPP_RET)ops_ret;
584     } break;
585     case IEP_CMD_QUERY_CAP : {
586         if (param)
587             *(IepHwCap **)param = &impl->cap;
588         else
589             mpp_err("Can NOT query to NULL output\n");
590     } break;
591     default : {
592         mpp_err("invalid command %d\n", cmd);
593         ret = MPP_NOK;
594     } break;
595     }
596 
597     return ret;
598 }
599 
600 static iep_com_ops iep_ops = {
601     .init = iep_init,
602     .deinit = iep_deinit,
603     .control = iep_control,
604     .reset = NULL,
605     .release = NULL,
606 };
607 
rockchip_iep_api_alloc_ctx(void)608 iep_com_ctx* rockchip_iep_api_alloc_ctx(void)
609 {
610     iep_com_ctx *com_ctx = (iep_com_ctx *)calloc(sizeof(*com_ctx), 1);
611     void *iep_ctx = calloc(sizeof(sizeof(void*)), 1);
612 
613     mpp_assert(com_ctx && iep_ctx);
614 
615     com_ctx->ops = &iep_ops;
616     com_ctx->priv = iep_ctx;
617 
618     return com_ctx;
619 }
620 
rockchip_iep_api_release_ctx(iep_com_ctx * com_ctx)621 void rockchip_iep_api_release_ctx(iep_com_ctx *com_ctx)
622 {
623     if (com_ctx->priv) {
624         free(com_ctx->priv);
625         com_ctx->priv = NULL;
626     }
627 
628     free(com_ctx);
629 }
630 
631