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