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