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