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