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