xref: /OK3568_Linux_fs/external/mpp/mpp/vproc/iep/test/iep_test.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_test"
18 
19 #include <string.h>
20 
21 #include "mpp_mem.h"
22 #include "mpp_time.h"
23 #include "mpp_debug.h"
24 #include "mpp_common.h"
25 #include "mpp_thread.h"
26 #include "mpp_buffer.h"
27 
28 #include "iep_api.h"
29 #include "utils.h"
30 #include "iniparser.h"
31 
32 #define MAX_URL_LEN                 (100)
33 #define ADD_OFFSET(base, offset)    ((RK_U32)base + ((RK_U32)(offset) << 10))
34 
35 typedef enum {
36     TEST_CASE_NONE,
37     TEST_CASE_DEINTERLACE,
38     TEST_CASE_YUVENHANCE,
39     TEST_CASE_RGBENHANCE,
40 } TEST_CASE;
41 
42 typedef struct IepTestCfg_t {
43     RK_S32      src_w;
44     RK_S32      src_h;
45     RK_S32      src_fmt;
46 
47     RK_S32      dst_w;
48     RK_S32      dst_h;
49     RK_S32      dst_fmt;
50 
51     char        src_url[MAX_URL_LEN];
52     char        dst_url[MAX_URL_LEN];
53     char        cfg_url[MAX_URL_LEN];
54 
55     FILE        *fp_src;
56     FILE        *fp_dst;
57 
58     TEST_CASE   mode;
59 
60     dictionary  *ini;
61     IepCmdParamDeiCfg       *dei_cfg;
62     IepCmdParamYuvEnhance   *yuv_enh;
63     IepCmdParamRgbEnhance   *rgb_enh;
64     IepCmdParamColorConvert *colorcvt;
65 } IepTestCfg;
66 
67 typedef struct IepTestInfo_t {
68     IepTestCfg *cfg;
69 
70     size_t src_size;
71     size_t dst_size;
72 
73     RK_U32 phy_src0;
74     RK_U32 phy_src1;
75     RK_U32 phy_dst0;
76     RK_U32 phy_dst1;
77 
78     RK_U8 *vir_src0;
79     RK_U8 *vir_src1;
80     RK_U8 *vir_dst0;
81     RK_U8 *vir_dst1;
82 
83     IepImg src;
84     IepImg dst;
85 
86     IepCtx                  ctx;
87 } IepTestInfo;
88 
parse_cfg(IepTestCfg * cfg)89 static void parse_cfg(IepTestCfg *cfg)
90 {
91     dictionary *ini = cfg->ini;
92 
93     cfg->dei_cfg = mpp_calloc(IepCmdParamDeiCfg, 1);
94     if (iniparser_find_entry(ini, "deinterlace")) {
95         mpp_assert(cfg->dei_cfg);
96         cfg->dei_cfg->dei_high_freq_en =
97             iniparser_getint(ini, "deinterlace:high_freq_en", 0);
98         cfg->dei_cfg->dei_mode =
99             (IepDeiMode)iniparser_getint(ini, "deinterlace:dei_mode", 0);
100         cfg->dei_cfg->dei_high_freq_fct =
101             iniparser_getint(ini, "deinterlace:dei_high_freq_fct", 0);
102         cfg->dei_cfg->dei_ei_mode =
103             iniparser_getint(ini, "deinterlace:dei_ei_mode", 0);
104         cfg->dei_cfg->dei_ei_smooth =
105             iniparser_getint(ini, "deinterlace:dei_ei_smooth", 0);
106         cfg->dei_cfg->dei_ei_sel =
107             iniparser_getint(ini, "deinterlace:dei_ei_sel", 0);
108         cfg->dei_cfg->dei_ei_radius =
109             iniparser_getint(ini, "deinterlace:dei_ei_radius", 0);
110     } else {
111         cfg->dei_cfg->dei_high_freq_en  = 1;
112         cfg->dei_cfg->dei_mode          = IEP_DEI_MODE_I4O1;
113         cfg->dei_cfg->dei_field_order   = IEP_DEI_FLD_ORDER_BOT_FIRST;
114         cfg->dei_cfg->dei_ei_mode       = 0;
115         cfg->dei_cfg->dei_ei_smooth     = 0;
116         cfg->dei_cfg->dei_ei_sel        = 0;
117         cfg->dei_cfg->dei_ei_radius     = 0;
118     }
119 
120     if (iniparser_find_entry(ini, "yuv enhance")) {
121         cfg->yuv_enh = mpp_calloc(IepCmdParamYuvEnhance, 1);
122         cfg->yuv_enh->saturation =
123             iniparser_getint(ini, "yuv enhance:saturation", 0);
124         cfg->yuv_enh->contrast =
125             iniparser_getint(ini, "yuv enhance:contrast", 0);
126         cfg->yuv_enh->brightness =
127             iniparser_getint(ini, "yuv enhance:brightness", 0);
128         cfg->yuv_enh->hue_angle =
129             iniparser_getint(ini, "yuv enhance:hue_angle", 0);
130         cfg->yuv_enh->video_mode =
131             (IepVideoMode)
132             iniparser_getint(ini, "yuv enhance:video_mode", 0);
133         cfg->yuv_enh->color_bar_y =
134             iniparser_getint(ini, "yuv enhance:color_bar_y", 0);
135         cfg->yuv_enh->color_bar_u =
136             iniparser_getint(ini, "yuv enhance:color_bar_u", 0);
137         cfg->yuv_enh->color_bar_v =
138             iniparser_getint(ini, "yuv enhance:color_bar_v", 0);
139     }
140 
141     if (iniparser_find_entry(ini, "rgb enhance")) {
142         cfg->rgb_enh = mpp_calloc(IepCmdParamRgbEnhance, 1);
143         cfg->rgb_enh->coe =
144             iniparser_getint(ini, "rgb enhance:coe", 0);
145         cfg->rgb_enh->mode =
146             (IepRgbEnhanceMode)
147             iniparser_getint(ini, "rgb enhance:mode", 0);
148         cfg->rgb_enh->cg_en =
149             iniparser_getint(ini, "rgb enhance:cg_en", 0);
150         cfg->rgb_enh->cg_rr =
151             iniparser_getint(ini, "rgb enhance:cg_rr", 0);
152         cfg->rgb_enh->cg_rg =
153             iniparser_getint(ini, "rgb enhance:cg_rg", 0);
154         cfg->rgb_enh->cg_rb =
155             iniparser_getint(ini, "rgb enhance:cg_rb", 0);
156         cfg->rgb_enh->order =
157             (IepRgbEnhanceOrder)
158             iniparser_getint(ini, "rgb enhance:order", 0);
159         cfg->rgb_enh->threshold =
160             iniparser_getint(ini, "rgb enhance:threshold", 0);
161         cfg->rgb_enh->alpha_num =
162             iniparser_getint(ini, "rgb enhance:alpha_num", 0);
163         cfg->rgb_enh->alpha_base =
164             iniparser_getint(ini, "rgb enhance:alpha_base", 0);
165         cfg->rgb_enh->radius =
166             iniparser_getint(ini, "rgb enhance:radius", 0);
167     }
168 
169     if (iniparser_find_entry(ini, "colorcvt")) {
170         cfg->colorcvt = mpp_calloc(IepCmdParamColorConvert, 1);
171         cfg->colorcvt->rgb2yuv_mode =
172             (IepColorConvertMode)
173             iniparser_getint(ini, "colorcvt:rgb2yuv_mode", 0);
174         cfg->colorcvt->yuv2rgb_mode =
175             (IepColorConvertMode)
176             iniparser_getint(ini, "colorcvt:yuv2rgb_mode", 0);
177         cfg->colorcvt->rgb2yuv_input_clip   =
178             iniparser_getint(ini, "colorcvt:rgb2yuv_input_clip", 0);
179         cfg->colorcvt->yuv2rgb_input_clip   =
180             iniparser_getint(ini, "colorcvt:yuv2rgb_input_clip", 0);
181         cfg->colorcvt->global_alpha_value   =
182             iniparser_getint(ini, "colorcvt:global_alpha_value", 0);
183         cfg->colorcvt->dither_up_en         =
184             iniparser_getint(ini, "colorcvt:dither_up_en", 0);
185         cfg->colorcvt->dither_down_en       =
186             iniparser_getint(ini, "colorcvt:dither_down_en", 0);
187     }
188 }
189 
get_image_size(RK_S32 w,RK_S32 h,RK_S32 fmt)190 static RK_S32 get_image_size(RK_S32 w, RK_S32 h, RK_S32 fmt)
191 {
192     RK_S32 img_size = 0;
193 
194     switch (fmt) {
195     case IEP_FORMAT_ABGR_8888:
196     case IEP_FORMAT_ARGB_8888:
197     case IEP_FORMAT_BGRA_8888:
198     case IEP_FORMAT_RGBA_8888:
199         img_size = w * h * 4;
200         break;
201     case IEP_FORMAT_BGR_565:
202     case IEP_FORMAT_RGB_565:
203     case IEP_FORMAT_YCbCr_422_P:
204     case IEP_FORMAT_YCbCr_422_SP:
205     case IEP_FORMAT_YCrCb_422_P:
206     case IEP_FORMAT_YCrCb_422_SP:
207         img_size = w * h * 2;
208         break;
209     case IEP_FORMAT_YCbCr_420_P:
210     case IEP_FORMAT_YCbCr_420_SP:
211     case IEP_FORMAT_YCrCb_420_P:
212     case IEP_FORMAT_YCrCb_420_SP:
213         img_size = w * h * 3 / 2;
214         break;
215     default : {
216     } break;
217     }
218     return img_size;
219 }
220 
config_iep_img(IepImg * img,RK_S32 w,RK_S32 h,RK_S32 fmt,RK_U32 base)221 static void config_iep_img(IepImg *img, RK_S32 w, RK_S32 h, RK_S32 fmt, RK_U32 base)
222 {
223     switch (fmt) {
224     case IEP_FORMAT_ABGR_8888:
225     case IEP_FORMAT_ARGB_8888:
226     case IEP_FORMAT_BGRA_8888:
227     case IEP_FORMAT_RGBA_8888:
228         img->v_addr = 0;
229         break;
230     case IEP_FORMAT_BGR_565:
231     case IEP_FORMAT_RGB_565:
232     case IEP_FORMAT_YCbCr_422_P:
233     case IEP_FORMAT_YCbCr_422_SP:
234     case IEP_FORMAT_YCrCb_422_P:
235     case IEP_FORMAT_YCrCb_422_SP:
236         img->v_addr = ADD_OFFSET(base, w * h + w * h / 2);
237         break;
238     case IEP_FORMAT_YCbCr_420_P:
239     case IEP_FORMAT_YCbCr_420_SP:
240     case IEP_FORMAT_YCrCb_420_P:
241     case IEP_FORMAT_YCrCb_420_SP:
242         img->v_addr = ADD_OFFSET(base, w * h + w * h / 4);
243         break;
244     default : {
245     } break;
246     }
247 
248     img->act_w      = w;
249     img->act_h      = h;
250     img->x_off      = 0;
251     img->y_off      = 0;
252     img->vir_w      = w;
253     img->vir_h      = h;
254     img->format     = fmt;
255     img->mem_addr   = base;
256     img->uv_addr    = ADD_OFFSET(base, w * h);
257 }
258 
iep_process_thread(void * param)259 void* iep_process_thread(void *param)
260 {
261     IepTestInfo *info = (IepTestInfo*)param;
262     IepTestCfg *cfg = info->cfg;
263 
264     config_iep_img(&info->src, cfg->src_w, cfg->src_h, cfg->src_fmt, info->phy_src0);
265     config_iep_img(&info->dst, cfg->dst_w, cfg->dst_h, cfg->dst_fmt, info->phy_dst0);
266 
267     if (info->src_size > fread(info->vir_src0, 1, info->src_size, cfg->fp_src)) {
268         mpp_err("read file failed\n");
269         return NULL;
270     }
271 
272     iep_control(info->ctx, IEP_CMD_INIT, NULL);
273     iep_control(info->ctx, IEP_CMD_SET_SRC, &info->src);
274     iep_control(info->ctx, IEP_CMD_SET_DST, &info->dst);
275 
276     switch (cfg->mode) {
277     case TEST_CASE_YUVENHANCE: {
278         iep_control(info->ctx, IEP_CMD_SET_YUV_ENHANCE, cfg->yuv_enh);
279     } break;
280     case TEST_CASE_RGBENHANCE: {
281         iep_control(info->ctx, IEP_CMD_SET_RGB_ENHANCE, cfg->rgb_enh);
282     } break;
283     case TEST_CASE_DEINTERLACE: {
284         IepImg src1;
285         IepImg dst1;
286 
287         if (info->src_size != fread(info->vir_src1, 1, info->src_size, cfg->fp_src))
288             mpp_err("failed to read %d from input\n", info->src_size);
289 
290         config_iep_img(&src1, cfg->src_w, cfg->src_h, cfg->src_fmt, info->phy_src1);
291         config_iep_img(&dst1, cfg->src_w, cfg->src_h, cfg->src_fmt, info->phy_dst1);
292 
293         iep_control(info->ctx, IEP_CMD_SET_DEI_SRC1, &src1);
294         iep_control(info->ctx, IEP_CMD_SET_DEI_DST1, &dst1);
295         iep_control(info->ctx, IEP_CMD_SET_DEI_CFG, cfg->dei_cfg);
296     } break;
297     default: {
298     } break;
299     }
300 
301     RK_S64 intime = mpp_time();
302     if (0 == iep_control(info->ctx, IEP_CMD_RUN_SYNC, NULL))
303         mpp_log("%d success\n", getpid());
304     else
305         mpp_log("%d failure\n", getpid());
306 
307     mpp_log("%s consume %lld ms\n", __func__, (mpp_time() - intime) / 1000);
308 
309     if (cfg->fp_dst)
310         fwrite(info->vir_dst0, 1, info->dst_size, cfg->fp_dst);
311 
312     return NULL;
313 }
314 
str_to_iep_fmt(const char * str)315 static RK_S32 str_to_iep_fmt(const char *str)
316 {
317     RK_S32 fmt = -1;
318 
319     if (!strcmp(str, "argb8888"))
320         fmt = IEP_FORMAT_ARGB_8888;
321     else if (!strcmp(str, "abgr8888"))
322         fmt = IEP_FORMAT_ABGR_8888;
323     else if (!strcmp(str, "rgba8888"))
324         fmt = IEP_FORMAT_BGRA_8888;
325     else if (!strcmp(str, "bgra8888"))
326         fmt = IEP_FORMAT_BGRA_8888;
327     else if (!strcmp(str, "rgb565"))
328         fmt = IEP_FORMAT_RGB_565;
329     else if (!strcmp(str, "bgr565"))
330         fmt = IEP_FORMAT_BGR_565;
331     else if (!strcmp(str, "yuv422sp"))
332         fmt = IEP_FORMAT_YCbCr_422_SP;
333     else if (!strcmp(str, "yuv422p"))
334         fmt = IEP_FORMAT_YCbCr_422_P;
335     else if (!strcmp(str, "yuv420sp"))
336         fmt = IEP_FORMAT_YCbCr_420_SP;
337     else if (!strcmp(str, "yuv420p"))
338         fmt = IEP_FORMAT_YCbCr_420_P;
339     else if (!strcmp(str, "yvu422sp"))
340         fmt = IEP_FORMAT_YCrCb_422_SP;
341     else if (!strcmp(str, "yvu422p"))
342         fmt = IEP_FORMAT_YCrCb_422_P;
343     else if (!strcmp(str, "yvu420sp"))
344         fmt = IEP_FORMAT_YCrCb_420_SP;
345     else if (!strcmp(str, "yvu420p"))
346         fmt = IEP_FORMAT_YCrCb_420_P;
347     else
348         mpp_err("invalid format %s\n", str);
349 
350     return fmt;
351 }
352 
check_input_cmd(IepTestCfg * cfg)353 static MPP_RET check_input_cmd(IepTestCfg *cfg)
354 {
355     MPP_RET ret = MPP_OK;
356 
357     if (cfg->src_w <= 0) {
358         mpp_err("non-positive input width %d\n", cfg->src_w);
359         ret = MPP_NOK;
360     }
361     if (cfg->src_h <= 0) {
362         mpp_err("non-positive input height %d\n", cfg->src_h);
363         ret = MPP_NOK;
364     }
365     if (cfg->src_fmt < IEP_FORMAT_ARGB_8888 ||
366         cfg->src_fmt > IEP_FORMAT_YCrCb_420_P) {
367         mpp_err("invalid input format\n");
368         ret = MPP_NOK;
369     }
370     if (cfg->fp_src == NULL) {
371         mpp_err("failed to open input file %s\n", cfg->src_url);
372         ret = MPP_NOK;
373     }
374     if (cfg->dst_w <= 0) {
375         mpp_err("non-positive input width %d\n", cfg->dst_w);
376         ret = MPP_NOK;
377     }
378     if (cfg->dst_h <= 0) {
379         mpp_err("non-positive input height %d\n", cfg->dst_h);
380         ret = MPP_NOK;
381     }
382     if (cfg->dst_fmt < IEP_FORMAT_ARGB_8888 ||
383         cfg->dst_fmt > IEP_FORMAT_YCrCb_420_P) {
384         mpp_err("invalid input format\n");
385         ret = MPP_NOK;
386     }
387     if (cfg->mode == TEST_CASE_NONE) {
388         mpp_err("invalid work mode\n");
389         ret = MPP_NOK;
390     }
391 
392     return ret;
393 }
394 
395 static OptionInfo iep_test_cmd[] = {
396     {"w",   "src_width",            "input  image width"},
397     {"h",   "src_height",           "input  image height"},
398     {"c",   "src_format",           "input  image format in ASCII string"},
399     {"f",   "src_file",             "input  image file name"},
400     {"W",   "dst_width",            "output image width"},
401     {"H",   "dst_height",           "output image height"},
402     {"C",   "dst_format",           "output image format in ASCII string"},
403     {"F",   "dst_file",             "output image file name"},
404     {"m",   "work_mode",            "working mode of iep in ASCII string"},
405     {"x",   "configure",            "configure file of working mode"},
406 };
407 
iep_test_help()408 static void iep_test_help()
409 {
410     mpp_log("usage: iep_test [options]\n");
411     mpp_log("*******************************\n");
412     show_options(iep_test_cmd);
413     mpp_log("*******************************\n");
414     mpp_log("supported ASCII format strings:\n");
415     mpp_log(" 0 - argb8888\n");
416     mpp_log(" 1 - abgr8888\n");
417     mpp_log(" 2 - rgba8888\n");
418     mpp_log(" 3 - bgra8888\n");
419     mpp_log(" 4 - rgb565\n");
420     mpp_log(" 5 - bgr565\n");
421     mpp_log(" 6 - yuv422sp\n");
422     mpp_log(" 7 - yuv422p\n");
423     mpp_log(" 8 - yuv420sp\n");
424     mpp_log(" 9 - yuv420p\n");
425     mpp_log("10 - yvu422sp\n");
426     mpp_log("11 - yvu422p\n");
427     mpp_log("12 - yvu420sp\n");
428     mpp_log("13 - yvu420p\n");
429     mpp_log("*******************************\n");
430     mpp_log("supported work mode strings:\n");
431     mpp_log(" 1 - deinterlace\n");
432     mpp_log(" 2 - yuvenhance\n");
433     mpp_log(" 3 - rgbenhance\n");
434     mpp_log("************ sample ***********\n");
435     mpp_log("iep_test -w 720 -h 480 -c yuv420p -f input.yuv -W 720 -H 480 -C yuv420p -F output.yuv -m deinterlace -x dil.cfg\n");
436 }
437 
main(int argc,char ** argv)438 int main(int argc, char **argv)
439 {
440     IepTestCfg cfg;
441     IepTestInfo info;
442     int ch;
443 
444     if (argc < 2) {
445         iep_test_help();
446         return 0;
447     }
448 
449     memset(&cfg, 0, sizeof(cfg));
450     memset(&info, 0, sizeof(info));
451     cfg.src_fmt = IEP_FORMAT_YCbCr_420_SP;
452     cfg.dst_fmt = IEP_FORMAT_YCbCr_420_SP;
453 
454     /// get options
455     opterr = 0;
456     while ((ch = getopt(argc, argv, "f:w:h:c:F:W:H:C:m:x:")) != -1) {
457         switch (ch) {
458         case 'w': {
459             cfg.src_w = atoi(optarg);
460         } break;
461         case 'h': {
462             cfg.src_h = atoi(optarg);
463         } break;
464         case 'c': {
465             cfg.src_fmt = str_to_iep_fmt(optarg);
466         } break;
467         case 'W': {
468             cfg.dst_w = atoi(optarg);
469         } break;
470         case 'H': {
471             cfg.dst_h = atoi(optarg);
472         } break;
473         case 'C': {
474             cfg.dst_fmt = str_to_iep_fmt(optarg);
475         } break;
476         case 'f': {
477             mpp_log("input filename: %s\n", optarg);
478             strncpy(cfg.src_url, optarg, sizeof(cfg.src_url) - 1);
479             cfg.fp_src = fopen(cfg.src_url, "rb");
480         } break;
481         case 'F': {
482             mpp_log("output filename: %s\n", optarg);
483             strncpy(cfg.dst_url, optarg, sizeof(cfg.dst_url) - 1);
484             cfg.fp_dst = fopen(cfg.dst_url, "w+b");
485         } break;
486         case 'm': {
487             if (!strcmp(optarg, "deinterlace")) {
488                 cfg.mode = TEST_CASE_DEINTERLACE;
489             } else if (!strcmp(optarg, "yuvenhance")) {
490                 cfg.mode = TEST_CASE_YUVENHANCE;
491             } else if (!strcmp(optarg, "rgbenhance")) {
492                 cfg.mode = TEST_CASE_RGBENHANCE;
493             } else {
494                 mpp_err("invalid work mode %s\n", optarg);
495                 cfg.mode = TEST_CASE_NONE;
496             }
497         } break;
498         case 'x': {
499             mpp_log("configure filename: %s\n", optarg);
500             strncpy(cfg.cfg_url, optarg, sizeof(cfg.cfg_url) - 1);
501             cfg.ini = iniparser_load(cfg.cfg_url);
502             if (cfg.ini)
503                 parse_cfg(&cfg);
504             else
505                 mpp_err("invalid configure file %s\n", optarg);
506         } break;
507         default: {
508         } break;
509         }
510     }
511 
512     if (check_input_cmd(&cfg)) {
513         mpp_err("failed to pass cmd line check\n");
514         iep_test_help();
515         return -1;
516     }
517 
518     info.cfg = &cfg;
519     info.src_size = get_image_size(cfg.src_w, cfg.src_h, cfg.src_fmt);
520     info.dst_size = get_image_size(cfg.dst_w, cfg.dst_h, cfg.dst_fmt);
521 
522     // allocate 12M in/out memory and initialize memory address
523     MppBuffer buffer = NULL;
524     size_t src_size = MPP_ALIGN(info.src_size, SZ_4K);
525     size_t dst_size = MPP_ALIGN(info.dst_size, SZ_4K);
526     // NOTE: deinterlace need 4 fields (2 frames) as input and output 2 frames
527     size_t total_size = src_size * 2 + dst_size * 2;
528 
529     mpp_buffer_get(NULL, &buffer, total_size);
530     mpp_assert(buffer);
531 
532     int buf_fd = mpp_buffer_get_fd(buffer);
533     RK_U8 *buf_ptr = (RK_U8 *)mpp_buffer_get_ptr(buffer);
534 
535     memset(buf_ptr, 0xff, total_size);
536 
537     info.phy_src0 = ADD_OFFSET(buf_fd, 0);
538     info.phy_src1 = ADD_OFFSET(buf_fd, src_size);
539     info.phy_dst0 = ADD_OFFSET(buf_fd, src_size * 2);
540     info.phy_dst1 = ADD_OFFSET(buf_fd, src_size * 2 + dst_size);
541 
542     info.vir_src0 = buf_ptr;
543     info.vir_src1 = buf_ptr + src_size;
544     info.vir_dst0 = buf_ptr + src_size * 2;
545     info.vir_dst1 = buf_ptr + src_size * 2 + dst_size;
546 
547     iep_init(&info.ctx);
548 
549     pthread_t td;
550     pthread_create(&td, NULL, iep_process_thread, &info);
551     pthread_join(td, NULL);
552 
553     if (info.ctx) {
554         iep_deinit(info.ctx);
555         info.ctx = NULL;
556     }
557 
558     if (cfg.fp_src) {
559         fclose(cfg.fp_src);
560         cfg.fp_src = NULL;
561     }
562 
563     if (cfg.fp_dst) {
564         fclose(cfg.fp_dst);
565         cfg.fp_dst = NULL;
566     }
567 
568     if (cfg.ini) {
569         iniparser_freedict(cfg.ini);
570         cfg.ini = NULL;
571         if (cfg.yuv_enh)
572             mpp_free(cfg.yuv_enh);
573         if (cfg.rgb_enh)
574             mpp_free(cfg.rgb_enh);
575         if (cfg.dei_cfg)
576             mpp_free(cfg.dei_cfg);
577         if (cfg.colorcvt)
578             mpp_free(cfg.colorcvt);
579     }
580 
581     mpp_buffer_put(buffer);
582 
583     return 0;
584 }
585