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