xref: /rockchip-linux_mpp/test/mpi_rc2_test.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3  * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
4  */
5 
6 #define MODULE_TAG "mpi_rc_test"
7 
8 #include <string.h>
9 #include <math.h>
10 
11 #include "rk_mpi.h"
12 
13 #include "mpp_env.h"
14 #include "mpp_mem.h"
15 #include "mpp_time.h"
16 #include "mpp_common.h"
17 
18 #include "mpi_dec_utils.h"
19 #include "mpi_enc_utils.h"
20 
21 #define MPI_BIT_DEPTH               8
22 #define MPI_PIXEL_MAX               ((1 << MPI_BIT_DEPTH) - 1)
23 
24 typedef RK_U8 pixel;
25 
26 typedef struct {
27     double          psnr_y;
28     double          ssim_y;
29     RK_U32          avg_bitrate; // Every sequence, byte per second
30     RK_U32          ins_bitrate; // Every second, byte per second
31     RK_U32          frame_size; // Every frame, byte
32 } MpiRcStat;
33 
34 typedef struct {
35     FILE *fp_input;
36     FILE *fp_enc_out;
37     FILE *fp_stat;
38 } MpiRcFile;
39 
40 typedef struct {
41     MpiEncTestArgs* enc_cmd;
42     MpiRcStat       stat;
43     MpiRcFile       file;
44 
45     RK_U8           *com_buf;
46     MppCtx          enc_ctx;
47     MppCtx          dec_ctx_post;
48     MppCtx          dec_ctx_pre;
49     MppApi          *enc_mpi;
50     MppApi          *dec_mpi_post;
51     MppApi          *dec_mpi_pre;
52 
53     /* 1. pre-decoder data */
54     FileReader      reader;
55     MppCodingType   dec_type;
56     RK_S32          pre_pkt_idx;
57     RK_S32          pre_frm_idx;
58     RK_S32          pre_frm_num;
59     MppPacket       dec_pkt_pre;
60     RK_U8           *dec_in_buf_pre;
61     RK_U32          dec_in_buf_pre_size;
62 
63     /* 2. encoder data */
64     MppBufferGroup  pkt_grp;
65     MppPacket       enc_pkt;
66 
67     MppEncRcCfg     rc_cfg;
68     MppEncPrepCfg   prep_cfg;
69 
70     MppTask         enc_in_task;
71     MppTask         enc_out_task;
72 
73     /* 3. post-decoder data */
74     MppPacket       dec_pkt_post;
75     RK_U8           *dec_in_buf_post;
76     RK_U32          dec_in_buf_post_size;
77 
78     RK_U32          loop_end;
79     RK_U32          pkt_eos;
80     RK_S32          frm_eos;
81     RK_U32          enc_pkt_eos;
82     MppEncCfg       cfg;
83 
84     RK_S32          frm_idx;
85     RK_U64          total_bits;
86     double          total_psnrs;
87     double          total_ssims;
88     RK_U32          calc_base_idx;
89     RK_U32          stream_size_1s;
90     pthread_t       dec_thr;
91     RK_S64          start_enc;
92 } MpiRc2TestCtx;
93 
mpi_rc_deinit(MpiRc2TestCtx * ctx)94 static void mpi_rc_deinit(MpiRc2TestCtx *ctx)
95 {
96     MpiRcFile *file = &ctx->file;
97 
98     if (file->fp_enc_out) {
99         fclose(file->fp_enc_out);
100         file->fp_enc_out = NULL;
101     }
102 
103     if (file->fp_stat) {
104         fclose(file->fp_stat);
105         file->fp_stat = NULL;
106     }
107 
108     if (file->fp_input) {
109         fclose(file->fp_input);
110         file->fp_input = NULL;
111     }
112 
113     if (ctx->reader) {
114         reader_deinit(ctx->reader);
115         ctx->reader = NULL;
116     }
117 
118     MPP_FREE(ctx->com_buf);
119 }
120 
mpi_rc_init(MpiRc2TestCtx * ctx)121 static MPP_RET mpi_rc_init(MpiRc2TestCtx *ctx)
122 {
123     MpiEncTestArgs* enc_cmd = ctx->enc_cmd;
124 
125     if (enc_cmd->file_input)
126         reader_init(&ctx->reader, enc_cmd->file_input, enc_cmd->type_src);
127 
128     if (NULL == ctx->reader) {
129         mpp_err("failed to open dec input file %s\n", enc_cmd->file_input);
130         return MPP_NOK;
131     }
132 
133     mpp_log("input file %s size %ld\n", enc_cmd->file_input, reader_size(ctx->reader));
134     ctx->dec_type = enc_cmd->type_src;
135 
136     if (enc_cmd->file_output) {
137         MpiRcFile *file = &ctx->file;
138 
139         file->fp_enc_out = fopen(enc_cmd->file_output, "w+b");
140         if (NULL == file->fp_enc_out) {
141             mpp_err("failed to open enc output file %s\n", enc_cmd->file_output);
142             return MPP_ERR_OPEN_FILE;
143         }
144     }
145 
146     return MPP_OK;
147 }
148 
mpi_rc_cmp_frame(MppFrame frame_in,MppFrame frame_out)149 static MPP_RET mpi_rc_cmp_frame(MppFrame frame_in, MppFrame frame_out)
150 {
151     void *enc_buf = mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_in));
152     void *dec_buf = mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_out));
153     RK_U32 enc_width  = mpp_frame_get_width(frame_in);
154     RK_U32 enc_height = mpp_frame_get_height(frame_in);
155     RK_U32 dec_width  = mpp_frame_get_width(frame_out);
156     RK_U32 dec_height = mpp_frame_get_height(frame_out);
157 
158     if (!enc_buf) {
159         mpp_err_f("enc buf is NULL");
160         return MPP_NOK;
161     }
162 
163     if (!dec_buf) {
164         mpp_err_f("dec buf is NULL");
165         return MPP_NOK;
166     }
167 
168     if (enc_width != dec_width) {
169         mpp_err_f("enc_width %d != dec_width %d", enc_width, dec_width);
170         return MPP_NOK;
171     }
172 
173     if (enc_height != dec_height) {
174         mpp_err_f("enc_height %d != dec_height %d", enc_height, dec_height);
175         return MPP_NOK;
176     }
177 
178     return MPP_OK;
179 }
180 
mpi_rc_calc_psnr(MpiRcStat * stat,MppFrame frame_in,MppFrame frame_out)181 static void mpi_rc_calc_psnr(MpiRcStat *stat, MppFrame frame_in,
182                              MppFrame frame_out)
183 {
184     RK_U32 x, y;
185     RK_S32 tmp;
186     double ssd_y = 0.0;
187     double mse_y = 0.0;
188     double psnr_y = 0.0;
189 
190     RK_U32 width  = mpp_frame_get_width(frame_in);
191     RK_U32 height  = mpp_frame_get_height(frame_in);
192     RK_U32 luma_size = width * height;
193     RK_U32 enc_hor_stride = mpp_frame_get_hor_stride(frame_in);
194     RK_U32 dec_hor_stride = mpp_frame_get_hor_stride(frame_out);
195     RK_U8 *enc_buf = (RK_U8 *)mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_in));
196     RK_U8 *dec_buf = (RK_U8 *)mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_out));
197     RK_U8 *enc_buf_y = enc_buf;
198     RK_U8 *dec_buf_y = dec_buf;
199 
200     for (y = 0 ; y < height; y++) {
201         for (x = 0; x < width; x++) {
202             tmp = enc_buf_y[x + y * enc_hor_stride] -
203                   dec_buf_y[x + y * dec_hor_stride];
204             tmp *= tmp;
205             ssd_y += tmp;
206         }
207     }
208     // NOTE: should be 65025.0 rather than 65025,
209     // because 65025*luma_size may exceed
210     // 1 << 32.
211     mse_y = ssd_y / (65025.0 * luma_size); // 65025=255*255
212     if (mse_y <= 0.0000000001)
213         psnr_y = 100;
214     else
215         psnr_y = -10.0 * log10f(mse_y);
216 
217     stat->psnr_y = psnr_y;
218 }
219 
ssim_end1(int s1,int s2,int ss,int s12)220 static float ssim_end1( int s1, int s2, int ss, int s12  )
221 {
222     /*
223      * Maximum value for 10-bit is: ss*64 = (2^10-1)^2*16*4*64 = 4286582784,
224      * which will overflow in some cases.
225      * s1*s1, s2*s2, and s1*s2 also obtain this value for edge cases:
226      * ((2^10-1)*16*4)^2 = 4286582784.
227      * Maximum value for 9-bit is: ss*64 = (2^9-1)^2*16*4*64 = 1069551616,
228      * which will not overflow.
229      */
230     static const int ssim_c1 =
231         (int)(.01 * .01 * MPI_PIXEL_MAX * MPI_PIXEL_MAX * 64 + .5);
232     static const int ssim_c2 =
233         (int)(.03 * .03 * MPI_PIXEL_MAX * MPI_PIXEL_MAX * 64 * 63 + .5);
234     int fs1 = s1;
235     int fs2 = s2;
236     int fss = ss;
237     int fs12 = s12;
238     int vars = fss * 64 - fs1 * fs1 - fs2 * fs2;
239     int covar = fs12 * 64 - fs1 * fs2;
240 
241     return (float)(2 * fs1 * fs2 + ssim_c1) *
242            (float)(2 * covar + ssim_c2) /
243            ((float)(fs1 * fs1 + fs2 * fs2 + ssim_c1) *
244             (float)(vars + ssim_c2));
245 }
246 
ssim_end4(int sum0[5][4],int sum1[5][4],int width)247 static float ssim_end4( int sum0[5][4], int sum1[5][4], int width  )
248 {
249     double ssim = 0.0;
250     int i  = 0;
251 
252     for (i = 0; i < width; i++  )
253         ssim += ssim_end1(sum0[i][0] + sum0[i + 1][0] +
254                           sum1[i][0] + sum1[i + 1][0],
255                           sum0[i][1] + sum0[i + 1][1] +
256                           sum1[i][1] + sum1[i + 1][1],
257                           sum0[i][2] + sum0[i + 1][2] +
258                           sum1[i][2] + sum1[i + 1][2],
259                           sum0[i][3] + sum0[i + 1][3] +
260                           sum1[i][3] + sum1[i + 1][3] );
261     return ssim;
262 }
263 
ssim_4x4x2_core(const pixel * pix1,intptr_t stride1,const pixel * pix2,intptr_t stride2,int sums[2][4])264 static void ssim_4x4x2_core( const pixel *pix1, intptr_t stride1,
265                              const pixel *pix2, intptr_t stride2,
266                              int sums[2][4]  )
267 {
268     int a = 0;
269     int b = 0;
270     int x = 0;
271     int y = 0;
272     int z = 0;
273 
274     for (z = 0; z < 2; z++  ) {
275         uint32_t s1 = 0, s2 = 0, ss = 0, s12 = 0;
276         for (y = 0; y < 4; y++  )
277             for ( x = 0; x < 4; x++  ) {
278                 a = pix1[x + y * stride1];
279                 b = pix2[x + y * stride2];
280                 s1  += a;
281                 s2  += b;
282                 ss  += a * a;
283                 ss  += b * b;
284                 s12 += a * b;
285 
286             }
287         sums[z][0] = s1;
288         sums[z][1] = s2;
289         sums[z][2] = ss;
290         sums[z][3] = s12;
291         pix1 += 4;
292         pix2 += 4;
293     }
294 }
295 
calc_ssim(pixel * pix1,RK_U32 stride1,pixel * pix2,RK_U32 stride2,int width,int height,void * buf,int * cnt)296 static float calc_ssim(pixel *pix1, RK_U32 stride1,
297                        pixel *pix2, RK_U32 stride2,
298                        int width, int height, void *buf, int *cnt)
299 {
300     int x = 0;
301     int y = 0;
302     int z = 0;
303     float ssim = 0.0;
304     int (*sum0)[4] = buf;
305     int (*sum1)[4] = sum0 + (width >> 2) + 3;
306 
307     width >>= 2;
308     height >>= 2;
309     for ( y = 1; y < height; y++  ) {
310         for ( ; z <= y; z++  ) {
311             MPP_SWAP( void*, sum0, sum1  );
312             for ( x = 0; x < width; x += 2  )
313                 ssim_4x4x2_core(&pix1[4 * (x + z * stride1)],
314                                 stride1, &pix2[4 * (x + z * stride2)],
315                                 stride2, &sum0[x]  );
316         }
317         for ( x = 0; x < width - 1; x += 4  )
318             ssim += ssim_end4(sum0 + x, sum1 + x,
319                               MPP_MIN(4, width - x - 1));
320 
321     }
322     *cnt = (height - 1) * (width - 1);
323     return ssim;
324 }
325 
mpi_rc_calc_ssim(MpiRc2TestCtx * ctx,MppFrame frame_in,MppFrame frame_out)326 static void mpi_rc_calc_ssim(MpiRc2TestCtx *ctx, MppFrame frame_in, MppFrame frame_out)
327 {
328     int cnt = 0;
329     float ssim = 0;
330     MpiRcStat *stat = &ctx->stat;
331     RK_U32 width  = mpp_frame_get_width(frame_in);
332     RK_U32 height  = mpp_frame_get_height(frame_in);
333     RK_U32 enc_hor_stride = mpp_frame_get_hor_stride(frame_in);
334     RK_U32 dec_hor_stride = mpp_frame_get_hor_stride(frame_out);
335     pixel *enc_buf =
336         (RK_U8 *)mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_in));
337     pixel *dec_buf =
338         (RK_U8 *)mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_out));
339     pixel *enc_buf_y = enc_buf;
340     pixel *dec_buf_y = dec_buf;
341 
342     if (NULL == ctx->com_buf)
343         ctx->com_buf = mpp_malloc(RK_U8, enc_hor_stride * mpp_frame_get_ver_stride(frame_out) * 2);
344 
345     ssim = calc_ssim(enc_buf_y, enc_hor_stride, dec_buf_y, dec_hor_stride,
346                      width - 2, height - 2, ctx->com_buf, &cnt);
347     ssim /= (float)cnt;
348 
349     stat->ssim_y = (double)ssim;
350 }
351 
mpi_rc_calc_stat(MpiRc2TestCtx * ctx,MppFrame frame_in,MppFrame frame_out)352 static MPP_RET mpi_rc_calc_stat(MpiRc2TestCtx *ctx,
353                                 MppFrame frame_in, MppFrame frame_out)
354 {
355     MPP_RET ret = MPP_OK;
356     MpiRcStat *stat = &ctx->stat;
357 
358     ret = mpi_rc_cmp_frame(frame_in, frame_out);
359     if (ret) {
360         mpp_err_f("mpi_rc_cmp_frame failed ret %d", ret);
361         return MPP_NOK;
362     }
363 
364     if (ctx->enc_cmd->psnr_en) {
365         mpi_rc_calc_psnr(stat, frame_in, frame_out);
366         ctx->total_psnrs += stat->psnr_y;
367     }
368     if (ctx->enc_cmd->ssim_en) {
369         mpi_rc_calc_ssim(ctx, frame_in, frame_out);
370         ctx->total_ssims += stat->ssim_y;
371     }
372 
373     return ret;
374 }
375 
mpi_rc_log_stat(MpiRc2TestCtx * ctx,RK_U32 frame_count,RK_U32 one_second,RK_U32 seq_end)376 static void mpi_rc_log_stat(MpiRc2TestCtx *ctx, RK_U32 frame_count,
377                             RK_U32 one_second, RK_U32 seq_end)
378 {
379     //static char rc_log_str[1024] = {0};
380     MpiRcStat *stat = &ctx->stat;
381     MpiRcFile *file  = &ctx->file;
382     FILE *fp  = file->fp_stat;
383 
384     mpp_log("frame %3d | frame_size %6d bytes | psnr %5.2f | ssim %5.5f",
385             frame_count, stat->frame_size, stat->psnr_y, stat->ssim_y);
386     if (one_second)
387         mpp_log("ins_bitrate %f kbps", stat->ins_bitrate * 8.0 / 1000);
388 
389     if (fp) {
390         fprintf(fp, "%3d,%6d,%5.2f,%5.5f,",
391                 frame_count, stat->frame_size, stat->psnr_y, stat->ssim_y);
392         if (one_second)
393             fprintf(fp, "bitsrate: %d,", stat->ins_bitrate);
394         if (!seq_end)
395             fprintf(fp, "\n");
396     }
397 }
398 
mpi_rc_enc_init(MpiRc2TestCtx * ctx)399 static MPP_RET mpi_rc_enc_init(MpiRc2TestCtx *ctx)
400 {
401     MpiEncTestArgs* enc_cmd = ctx->enc_cmd;
402     MppApi *enc_mpi = NULL;
403     MppCtx enc_ctx = NULL;
404     MppPollType block = MPP_POLL_NON_BLOCK;
405     MppEncRcCfg *rc_cfg = &ctx->rc_cfg;
406     MppEncSeiMode sei_mode = MPP_ENC_SEI_MODE_ONE_SEQ;
407     MppEncCfg cfg = ctx->cfg;
408     RK_U32 debreath_en = 0;
409     RK_U32 debreath_s = 0;
410     MPP_RET ret = MPP_OK;
411 
412     // encoder init
413     ret = mpp_create(&ctx->enc_ctx, &ctx->enc_mpi);
414     if (ret) {
415         mpp_err("mpp_create encoder failed\n");
416         goto MPP_TEST_OUT;
417     }
418 
419     enc_mpi = ctx->enc_mpi;
420     enc_ctx = ctx->enc_ctx;
421 
422     rc_cfg->fps_in_denom = 1;
423     rc_cfg->fps_out_denom = 1;
424     rc_cfg->fps_in_num = 30;
425     rc_cfg->fps_out_num = 30;
426     rc_cfg->fps_in_flex = 0;
427     rc_cfg->fps_out_flex = 0;
428     rc_cfg->max_reenc_times = 1;
429     rc_cfg->gop = enc_cmd->gop_len;
430 
431     block = MPP_POLL_BLOCK;
432     ret = enc_mpi->control(enc_ctx, MPP_SET_INPUT_TIMEOUT, (MppParam)&block);
433     if (ret) {
434         mpp_err("enc_mpi->control MPP_SET_INPUT_TIMEOUT failed\n");
435         goto MPP_TEST_OUT;
436     }
437     block = MPP_POLL_BLOCK;
438     ret = enc_mpi->control(enc_ctx, MPP_SET_OUTPUT_TIMEOUT, (MppParam)&block);
439     if (ret) {
440         mpp_err("enc_mpi->control MPP_SET_OUTPUT_TIMEOUT failed\n");
441         goto MPP_TEST_OUT;
442     }
443 
444     ret = mpp_init(enc_ctx, MPP_CTX_ENC, enc_cmd->type);
445     if (ret) {
446         mpp_err("mpp_init enc failed\n");
447         goto MPP_TEST_OUT;
448     }
449 
450     if (enc_cmd->width)
451         mpp_enc_cfg_set_s32(cfg, "prep:width", enc_cmd->width);
452     if (enc_cmd->height)
453         mpp_enc_cfg_set_s32(cfg, "prep:height", enc_cmd->height);
454     if (enc_cmd->hor_stride)
455         mpp_enc_cfg_set_s32(cfg, "prep:hor_stride", enc_cmd->hor_stride);
456     if (enc_cmd->ver_stride)
457         mpp_enc_cfg_set_s32(cfg, "prep:ver_stride", enc_cmd->ver_stride);
458     mpp_enc_cfg_set_s32(cfg, "prep:format", MPP_FMT_YUV420SP);
459 
460     mpp_enc_cfg_set_s32(cfg, "rc:mode",  enc_cmd->rc_mode);
461 
462     switch (enc_cmd->rc_mode) {
463     case MPP_ENC_RC_MODE_FIXQP : {
464         /* do not set bps on fix qp mode */
465     } break;
466     case MPP_ENC_RC_MODE_CBR : {
467         /* CBR mode has narrow bound */
468         mpp_enc_cfg_set_s32(cfg, "rc:bps_target", enc_cmd->bps_target);
469         mpp_enc_cfg_set_s32(cfg, "rc:bps_max", enc_cmd->bps_max ? enc_cmd->bps_max : enc_cmd->bps_target * 3 / 2);
470         mpp_enc_cfg_set_s32(cfg, "rc:bps_min", enc_cmd->bps_min ? enc_cmd->bps_max : enc_cmd->bps_target / 2);
471     } break;
472     case MPP_ENC_RC_MODE_VBR : {
473         /* CBR mode has wide bound */
474         mpp_enc_cfg_set_s32(cfg, "rc:bps_target", enc_cmd->bps_target);
475         mpp_enc_cfg_set_s32(cfg, "rc:bps_max", enc_cmd->bps_max ? enc_cmd->bps_max : enc_cmd->bps_target * 17 / 16);
476         mpp_enc_cfg_set_s32(cfg, "rc:bps_min", enc_cmd->bps_min ? enc_cmd->bps_max : enc_cmd->bps_target * 1 / 16);
477     } break;
478     default : {
479         mpp_err_f("unsupport encoder rc mode %d\n", enc_cmd->rc_mode);
480     } break;
481     }
482 
483     /* fix input / output frame rate */
484     mpp_enc_cfg_set_s32(cfg, "rc:fps_in_flex", rc_cfg->fps_in_flex);
485     mpp_enc_cfg_set_s32(cfg, "rc:fps_in_num", rc_cfg->fps_in_num);
486     mpp_enc_cfg_set_s32(cfg, "rc:fps_in_denom",  rc_cfg->fps_in_denom);
487     mpp_enc_cfg_set_s32(cfg, "rc:fps_out_flex", rc_cfg->fps_out_flex);
488     mpp_enc_cfg_set_s32(cfg, "rc:fps_out_num",  rc_cfg->fps_out_num);
489     mpp_enc_cfg_set_s32(cfg, "rc:fps_out_denom", rc_cfg->fps_out_denom);
490     mpp_enc_cfg_set_s32(cfg, "rc:gop", enc_cmd->gop_len ? enc_cmd->gop_len : 30 * 2);
491 
492     /* drop frame or not when bitrate overflow */
493     mpp_enc_cfg_set_u32(cfg, "rc:drop_mode", MPP_ENC_RC_DROP_FRM_DISABLED);
494     mpp_enc_cfg_set_u32(cfg, "rc:drop_thd", 20);        /* 20% of max bps */
495     mpp_enc_cfg_set_u32(cfg, "rc:drop_gap", 1);         /* Do not continuous drop frame */
496 
497     mpp_env_get_u32("dbrh_en", &debreath_en, 0);
498     mpp_env_get_u32("dbrh_s",  &debreath_s, 16);
499 
500     mpp_enc_cfg_set_u32(cfg, "rc:debreath_en", debreath_en);
501     mpp_enc_cfg_set_u32(cfg, "rc:debreath_strength", debreath_s);
502 
503     /* setup codec  */
504     mpp_enc_cfg_set_s32(cfg, "codec:type",  enc_cmd->type);
505     switch (enc_cmd->type) {
506     case MPP_VIDEO_CodingAVC : {
507         /*
508          * H.264 profile_idc parameter
509          * 66  - Baseline profile
510          * 77  - Main profile
511          * 100 - High profile
512          */
513         mpp_enc_cfg_set_s32(cfg, "h264:profile", 100);
514         /*
515          * H.264 level_idc parameter
516          * 10 / 11 / 12 / 13    - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
517          * 20 / 21 / 22         - cif@30fps / half-D1@@25fps / D1@12.5fps
518          * 30 / 31 / 32         - D1@25fps / 720p@30fps / 720p@60fps
519          * 40 / 41 / 42         - 1080p@30fps / 1080p@30fps / 1080p@60fps
520          * 50 / 51 / 52         - 4K@30fps
521          */
522         mpp_enc_cfg_set_s32(cfg, "h264:level", 40);
523         mpp_enc_cfg_set_s32(cfg, "h264:cabac_en", 1);
524         mpp_enc_cfg_set_s32(cfg, "h264:cabac_idc", 0);
525         mpp_enc_cfg_set_s32(cfg, "h264:trans8x8", 1);
526 
527         if (enc_cmd->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
528             mpp_enc_cfg_set_s32(cfg, "h264:qp_init", 20);
529             mpp_enc_cfg_set_s32(cfg, "h264:qp_max", 16);
530             mpp_enc_cfg_set_s32(cfg, "h264:qp_min", 16);
531             mpp_enc_cfg_set_s32(cfg, "h264:qp_max_i", 20);
532             mpp_enc_cfg_set_s32(cfg, "h264:qp_min_i", 20);
533         } else {
534             mpp_enc_cfg_set_s32(cfg, "h264:qp_init", 26);
535             mpp_enc_cfg_set_s32(cfg, "h264:qp_max", 51);
536             mpp_enc_cfg_set_s32(cfg, "h264:qp_min", 10);
537             mpp_enc_cfg_set_s32(cfg, "h264:qp_max_i", 46);
538             mpp_enc_cfg_set_s32(cfg, "h264:qp_min_i", 18);
539         }
540     } break;
541     case MPP_VIDEO_CodingMJPEG : {
542         mpp_enc_cfg_set_s32(cfg, "jpeg:q_factor", 80);
543         mpp_enc_cfg_set_s32(cfg, "jpeg:qf_max", 99);
544         mpp_enc_cfg_set_s32(cfg, "jpeg:qf_min", 1);
545     } break;
546     case MPP_VIDEO_CodingVP8 : {
547         mpp_enc_cfg_set_s32(cfg, "vp8:qp_init", 40);
548         mpp_enc_cfg_set_s32(cfg, "vp8:qp_max",  127);
549         mpp_enc_cfg_set_s32(cfg, "vp8:qp_min",  0);
550         mpp_enc_cfg_set_s32(cfg, "vp8:qp_max_i", 127);
551         mpp_enc_cfg_set_s32(cfg, "vp8:qp_min_i", 0);
552     } break;
553     case MPP_VIDEO_CodingHEVC : {
554         mpp_enc_cfg_set_s32(cfg, "h265:qp_init", enc_cmd->rc_mode == MPP_ENC_RC_MODE_FIXQP ? -1 : 26);
555         mpp_enc_cfg_set_s32(cfg, "h265:qp_max", 51);
556         mpp_enc_cfg_set_s32(cfg, "h265:qp_min", 10);
557         mpp_enc_cfg_set_s32(cfg, "h265:qp_max_i", 46);
558         mpp_enc_cfg_set_s32(cfg, "h265:qp_min_i", 18);
559     } break;
560     default : {
561         mpp_err_f("unsupport encoder coding type %d\n",  enc_cmd->type);
562     } break;
563     }
564 
565     ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_CFG, cfg);
566     if (ret) {
567         mpp_err("mpi control enc set cfg failed ret %d\n", ret);
568         goto MPP_TEST_OUT;
569     }
570 
571     /* optional */
572     ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_SEI_CFG, &sei_mode);
573     if (ret) {
574         mpp_err("mpi control enc set sei cfg failed ret %d\n", ret);
575         goto MPP_TEST_OUT;
576     }
577 MPP_TEST_OUT:
578     return ret;
579 }
580 
mpi_rc_post_dec_init(MpiRc2TestCtx * ctx)581 static MPP_RET mpi_rc_post_dec_init(MpiRc2TestCtx *ctx)
582 {
583     MpiEncTestArgs *enc_cmd = ctx->enc_cmd;
584     MppApi *dec_mpi = NULL;
585     MppCtx dec_ctx = NULL;
586     MppPollType block = MPP_POLL_NON_BLOCK;
587     RK_U32 need_split = 0;
588     MPP_RET ret = MPP_OK;
589 
590     // decoder init
591     ret = mpp_create(&ctx->dec_ctx_post, &ctx->dec_mpi_post);
592     if (ret) {
593         mpp_err("mpp_create decoder failed\n");
594         goto MPP_TEST_OUT;
595     }
596 
597     dec_mpi = ctx->dec_mpi_post;
598     dec_ctx = ctx->dec_ctx_post;
599 
600     ret = mpp_packet_init(&ctx->dec_pkt_post,
601                           ctx->dec_in_buf_post, ctx->dec_in_buf_post_size);
602     if (ret) {
603         mpp_err("mpp_packet_init failed\n");
604         goto MPP_TEST_OUT;
605     }
606 
607     ret = dec_mpi->control(dec_ctx, MPP_DEC_SET_PARSER_SPLIT_MODE, &need_split);
608     if (ret) {
609         mpp_err("dec_mpi->control failed\n");
610         goto MPP_TEST_OUT;
611     }
612     ret = dec_mpi->control(dec_ctx, MPP_SET_INPUT_TIMEOUT, (MppParam)&block);
613     if (ret) {
614         mpp_err("dec_mpi->control dec MPP_SET_INPUT_TIMEOUT failed\n");
615         goto MPP_TEST_OUT;
616     }
617 
618     block = MPP_POLL_NON_BLOCK;
619     ret = dec_mpi->control(dec_ctx, MPP_SET_OUTPUT_TIMEOUT, (MppParam)&block);
620     if (ret) {
621         mpp_err("dec_mpi->control MPP_SET_OUTPUT_TIMEOUT failed\n");
622         goto MPP_TEST_OUT;
623     }
624 
625     ret = mpp_init(dec_ctx, MPP_CTX_DEC, enc_cmd->type);
626     if (ret) {
627         mpp_err("mpp_init dec failed\n");
628         goto MPP_TEST_OUT;
629     }
630 
631 MPP_TEST_OUT:
632 
633     return ret;
634 }
635 
mpi_rc_dec_post_decode(MpiRc2TestCtx * ctx,MppFrame orig_frm)636 static MPP_RET mpi_rc_dec_post_decode(MpiRc2TestCtx *ctx, MppFrame orig_frm)
637 {
638     MPP_RET ret = MPP_OK;
639     RK_S32 dec_pkt_done = 0;
640     MppFrame out_frm = NULL;
641 
642     do {
643         if (ctx->pkt_eos)
644             mpp_packet_set_eos(ctx->dec_pkt_post);
645 
646         // send the packet first if packet is not done
647         if (!dec_pkt_done) {
648             ret = ctx->dec_mpi_post->decode_put_packet(ctx->dec_ctx_post,
649                                                        ctx->dec_pkt_post);
650             if (MPP_OK == ret)
651                 dec_pkt_done = 1;
652         }
653 
654         // then get all available frame and release
655         do {
656             RK_S32 dec_get_frm = 0;
657             RK_U32 dec_frm_eos = 0;
658 
659             ret = ctx->dec_mpi_post->decode_get_frame(ctx->dec_ctx_post,
660                                                       &out_frm);
661             if (ret) {
662                 mpp_err("decode_get_frame failed ret %d\n", ret);
663                 break;
664             }
665 
666             if (out_frm) {
667                 if (mpp_frame_get_info_change(out_frm)) {
668                     mpp_log("decode_get_frame get info changed found\n");
669                     ctx->dec_mpi_post->control(ctx->dec_ctx_post,
670                                                MPP_DEC_SET_INFO_CHANGE_READY,
671                                                NULL);
672                 } else {
673                     mpi_rc_calc_stat(ctx, orig_frm, out_frm);
674                     mpi_rc_log_stat(ctx, ctx->frm_idx,
675                                     !((ctx->frm_idx - ctx->calc_base_idx + 1) %
676                                       ctx->rc_cfg.fps_in_num),
677                                     0);
678                     dec_get_frm = 1;
679                 }
680                 dec_frm_eos = mpp_frame_get_eos(out_frm);
681                 mpp_frame_deinit(&out_frm);
682                 out_frm = NULL;
683             }
684 
685             // if last packet is send but last frame is not found continue
686             if (ctx->pkt_eos && dec_pkt_done && !dec_frm_eos)
687                 continue;
688 
689             if (dec_get_frm)
690                 break;
691         } while (1);
692 
693         if (dec_pkt_done)
694             break;
695 
696         msleep(5);
697     } while (1);
698 
699     return ret;
700 }
701 
mpi_rc_pre_dec_init(MpiRc2TestCtx * ctx)702 static MPP_RET mpi_rc_pre_dec_init(MpiRc2TestCtx *ctx)
703 {
704     RK_U32 need_split = 1;
705     MppPollType block = MPP_POLL_NON_BLOCK;
706     RK_U32 fast_en = 0;
707     MppApi *dec_mpi = NULL;
708     MppCtx dec_ctx = NULL;
709     MppFrameFormat format = MPP_FMT_YUV420SP;
710     RK_U32 fbc_en = 0;
711     MPP_RET ret = MPP_OK;
712 
713     mpp_env_get_u32("fbc_dec_en", &fbc_en, 0);
714     mpp_env_get_u32("fast_en", &fast_en, 0);
715 
716     if (fbc_en)
717         format = format | MPP_FRAME_FBC_AFBC_V2;
718 
719     // decoder init
720     ret = mpp_create(&ctx->dec_ctx_pre, &ctx->dec_mpi_pre);
721     if (ret) {
722         mpp_err("mpp_create decoder failed\n");
723         goto MPP_TEST_OUT;
724     }
725 
726     dec_mpi = ctx->dec_mpi_pre;
727     dec_ctx = ctx->dec_ctx_pre;
728 
729     ret = mpp_packet_init(&ctx->dec_pkt_pre, ctx->dec_in_buf_pre, ctx->dec_in_buf_pre_size);
730     if (ret) {
731         mpp_err("mpp_packet_init failed\n");
732         goto MPP_TEST_OUT;
733     }
734 
735     ret = dec_mpi->control(dec_ctx, MPP_DEC_SET_PARSER_SPLIT_MODE, &need_split);
736     if (ret) {
737         mpp_err("dec_mpi->control failed\n");
738         goto MPP_TEST_OUT;
739     }
740 
741     ret = dec_mpi->control(dec_ctx, MPP_DEC_SET_PARSER_FAST_MODE, &fast_en);
742     if (ret) {
743         mpp_err("dec_mpi->control failed\n");
744         goto MPP_TEST_OUT;
745     }
746 
747     ret = dec_mpi->control(dec_ctx, MPP_SET_INPUT_TIMEOUT, (MppParam)&block);
748     if (ret) {
749         mpp_err("dec_mpi->control dec MPP_SET_INPUT_TIMEOUT failed\n");
750         goto MPP_TEST_OUT;
751     }
752 
753     block = MPP_POLL_NON_BLOCK;
754     ret = dec_mpi->control(dec_ctx, MPP_SET_OUTPUT_TIMEOUT, (MppParam)&block);
755     if (ret) {
756         mpp_err("dec_mpi->control MPP_SET_OUTPUT_TIMEOUT failed\n");
757         goto MPP_TEST_OUT;
758     }
759 
760     ret = mpp_init(dec_ctx, MPP_CTX_DEC, ctx->dec_type);
761     if (ret) {
762         mpp_err("mpp_init dec failed\n");
763         goto MPP_TEST_OUT;
764     }
765 
766     ret = dec_mpi->control(dec_ctx, MPP_DEC_SET_OUTPUT_FORMAT, &format);
767     if (ret) {
768         mpp_err("dec_mpi->control failed\n");
769         goto MPP_TEST_OUT;
770     }
771 
772 MPP_TEST_OUT:
773     return ret;
774 }
775 
mpi_rc_info_change(MpiRc2TestCtx * ctx,MppFrame frm)776 static MPP_RET mpi_rc_info_change(MpiRc2TestCtx *ctx, MppFrame frm)
777 {
778     MPP_RET ret = MPP_OK;
779 
780     mpp_enc_cfg_set_s32(ctx->cfg, "prep:width", mpp_frame_get_width(frm));
781     mpp_enc_cfg_set_s32(ctx->cfg, "prep:height", mpp_frame_get_height(frm));
782     mpp_enc_cfg_set_s32(ctx->cfg, "prep:hor_stride",  mpp_frame_get_hor_stride(frm));
783     mpp_enc_cfg_set_s32(ctx->cfg, "prep:ver_stride", mpp_frame_get_ver_stride(frm));
784     mpp_enc_cfg_set_s32(ctx->cfg, "prep:format", mpp_frame_get_fmt(frm));
785 
786     ret = ctx->enc_mpi->control(ctx->enc_ctx, MPP_ENC_SET_CFG, ctx->cfg);
787 
788     ctx->dec_mpi_post->control(ctx->dec_ctx_post, MPP_DEC_SET_FRAME_INFO, (MppParam)frm);
789 
790     return ret;
791 }
792 
mpi_rc_enc(MpiRc2TestCtx * ctx)793 static MPP_RET mpi_rc_enc(MpiRc2TestCtx *ctx)
794 {
795     MPP_RET ret = MPP_OK;
796     MppApi *mpi = ctx->dec_mpi_pre;
797     MppCtx dec_ctx = ctx->dec_ctx_pre;
798     MppFrame frm = NULL;
799 
800     do {
801         ret = mpi->decode_get_frame(dec_ctx, &frm);
802         if (ret) {
803             mpp_err("decode_get_frame failed ret %d\n", ret);
804             break;
805         }
806 
807         if (frm) {
808             ctx->frm_eos = mpp_frame_get_eos(frm);
809             if (mpp_frame_get_info_change(frm)) {
810                 mpp_log("decode_get_frame get info changed found\n");
811                 mpi->control(dec_ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);
812                 mpi_rc_info_change(ctx, frm);
813                 ctx->start_enc = mpp_time();
814             } else {
815                 void *ptr;
816                 size_t len;
817                 /*force eos*/
818                 if ((ctx->enc_cmd->frame_num > 0) && (ctx->frm_idx > ctx->enc_cmd->frame_num)) {
819                     ctx->loop_end = 1;
820                     mpp_frame_set_eos(frm, 1);
821                     ctx->frm_eos = mpp_frame_get_eos(frm);
822                 }
823 #ifndef ASYN_ENC
824                 ctx->enc_mpi->encode_put_frame(ctx->enc_ctx, frm);
825                 ctx->enc_mpi->encode_get_packet(ctx->enc_ctx, &ctx->enc_pkt);
826 #else
827             LAST_PACKET:
828                 ctx->enc_mpi->encode(ctx->enc_ctx, frm, &ctx->enc_pkt);
829                 frm = NULL; //ASYN_ENC will free after get packet
830 #endif
831                 if (ctx->enc_pkt) {
832                     len = mpp_packet_get_length(ctx->enc_pkt);
833                     ctx->stat.frame_size = len;
834                     ctx->stream_size_1s += len;
835                     ctx->total_bits += len * 8;
836                     if ((ctx->frm_idx - ctx->calc_base_idx + 1) %
837                         ctx->rc_cfg.fps_in_num == 0) {
838                         ctx->stat.ins_bitrate = ctx->stream_size_1s;
839                         ctx->stream_size_1s = 0;
840                     }
841 
842                     ptr = mpp_packet_get_pos(ctx->enc_pkt);
843                     if (ctx->file.fp_enc_out)
844                         fwrite(ptr, 1, len, ctx->file.fp_enc_out);
845 
846                     /* check post packet first */
847                     if (len > ctx->dec_in_buf_post_size) {
848                         RK_U32 buf_size = MPP_ALIGN(len, SZ_4K);
849 
850                         ctx->dec_in_buf_post = mpp_realloc(ctx->dec_in_buf_post, RK_U8, buf_size);
851                         ctx->dec_in_buf_post_size = buf_size;
852 
853                         mpp_packet_set_data(ctx->dec_pkt_post, ctx->dec_in_buf_post);
854                         mpp_packet_set_size(ctx->dec_pkt_post, buf_size);
855                         mpp_packet_set_pos(ctx->dec_pkt_post, ctx->dec_in_buf_post);
856                         mpp_packet_set_length(ctx->dec_pkt_post, 0);
857                     }
858 
859                     /* decode one frame */
860                     // write packet to dec input
861                     mpp_packet_write(ctx->dec_pkt_post, 0, ptr, len);
862                     // reset pos
863                     mpp_packet_set_pos(ctx->dec_pkt_post, ctx->dec_in_buf_post);
864                     mpp_packet_set_length(ctx->dec_pkt_post, len);
865                     mpp_packet_set_size(ctx->dec_pkt_post, len);
866 
867                     if (mpp_packet_has_meta(ctx->enc_pkt)) {
868                         MppFrame frame = NULL;
869                         MppMeta meta = mpp_packet_get_meta(ctx->enc_pkt);
870                         mpp_meta_get_frame(meta,  KEY_INPUT_FRAME, &frame);
871                         if (ctx->enc_cmd->ssim_en || ctx->enc_cmd->psnr_en) {
872                             mpp_packet_write(ctx->dec_pkt_post, 0, ptr, len);
873                             mpi_rc_dec_post_decode(ctx, frame);
874                         }
875                         if (frame) {
876                             frm = frame;  //ASYN_ENC delay free
877                         }
878                     } else {
879                         if (ctx->enc_cmd->ssim_en || ctx->enc_cmd->psnr_en) {
880                             mpp_packet_write(ctx->dec_pkt_post, 0, ptr, len);
881                             mpi_rc_dec_post_decode(ctx, frm);
882                         }
883                     }
884                     ctx->enc_pkt_eos = mpp_packet_get_eos(ctx->enc_pkt);
885                     ctx->frm_idx++;
886                     mpp_packet_deinit(&ctx->enc_pkt);
887                 }
888 
889             }
890             mpp_frame_deinit(&frm);
891             frm = NULL;
892         } else {
893             msleep(3);
894             continue;
895         }
896 #ifdef ANSY_ENC
897         if (ctx->frm_eos && !ctx->enc_pkt_eos) {
898             goto LAST_PACKET;
899         }
900 #endif
901         if (ctx->enc_pkt_eos) {
902             break;
903         }
904     } while (1);
905     return ret;
906 }
907 
mpi_rc_buffer_init(MpiRc2TestCtx * ctx)908 static MPP_RET mpi_rc_buffer_init(MpiRc2TestCtx *ctx)
909 {
910     /* NOTE: packet buffer may overflow */
911     size_t packet_size  = SZ_256K;
912     MPP_RET ret = MPP_OK;
913 
914     ret = mpp_buffer_group_get_internal(&ctx->pkt_grp, MPP_BUFFER_TYPE_ION);
915     if (ret) {
916         mpp_err("failed to get buffer group for output packet ret %d\n", ret);
917         goto RET;
918     }
919 
920     ctx->dec_in_buf_post = mpp_calloc(RK_U8, packet_size);
921     if (NULL == ctx->dec_in_buf_post) {
922         mpp_err("mpi_dec_test malloc input stream buffer failed\n");
923         goto RET;
924     }
925 
926     ctx->dec_in_buf_post_size = packet_size;
927 
928     ctx->frm_idx = 0;
929     ctx->calc_base_idx = 0;
930     ctx->stream_size_1s = 0;
931 
932     return ret;
933 RET:
934     ctx->dec_ctx_pre = NULL;
935     ctx->dec_ctx_post = NULL;
936     MPP_FREE(ctx->dec_in_buf_post);
937 
938     if (ctx->pkt_grp) {
939         mpp_buffer_group_put(ctx->pkt_grp);
940         ctx->pkt_grp = NULL;
941     }
942 
943     return ret;
944 }
945 
946 #define CHECK_RET(x)    do { \
947                             if (x < 0) { \
948                                 mpp_err_f("%d failed\n"); \
949                                 goto MPP_TEST_OUT; \
950                             } \
951                         } while (0)
952 
rc2_pre_dec_thread(void * param)953 static void *rc2_pre_dec_thread(void *param)
954 {
955     MpiRc2TestCtx *ctx = (MpiRc2TestCtx *)param;
956     FileReader reader = ctx->reader;
957     FileBufSlot *slot = NULL;
958     MppPacket packet = ctx->dec_pkt_pre;
959     MppApi *mpi = ctx->dec_mpi_pre;
960     MppCtx dec_ctx = ctx->dec_ctx_pre;
961     MPP_RET ret = MPP_OK;
962     RK_S32 dec_pkt_done = 0;
963 
964     while (!ctx->loop_end) {
965         RK_U32 pkt_eos  = 0;
966         dec_pkt_done = 0;
967         ret = reader_index_read(reader, ctx->pre_pkt_idx++, &slot);
968         pkt_eos = slot->eos;
969         if (pkt_eos) {
970             if (ctx->enc_cmd->frame_num < 0) {
971                 ctx->pre_pkt_idx = 0;
972                 pkt_eos = 0;
973             } else if (!ctx->enc_cmd->frame_num) {
974                 ctx->loop_end = 1;
975             } else {
976                 ctx->pre_pkt_idx = 0;
977                 pkt_eos = 0;
978             }
979         }
980 
981         if ((ctx->enc_cmd->frame_num > 0) && (ctx->frm_idx > ctx->enc_cmd->frame_num)) {
982             mpp_log("frm_idx %d, frame_num %d",
983                     ctx->frm_idx, ctx->enc_cmd->frame_num);
984             ctx->loop_end = 1;
985         }
986         mpp_packet_set_data(packet, slot->data);
987         mpp_packet_set_size(packet, slot->size);
988         mpp_packet_set_pos(packet, slot->data);
989         mpp_packet_set_length(packet, slot->size);
990 
991         if (ctx->loop_end) {
992             mpp_packet_set_eos(packet);
993             ctx->pkt_eos = 1;
994         }
995 
996         do {
997             ret = mpi->decode_put_packet(dec_ctx, packet);
998             if (MPP_OK == ret)
999                 dec_pkt_done = 1;
1000             else
1001                 msleep(5);
1002             if (ctx->loop_end) {
1003                 break;
1004             }
1005         } while (!dec_pkt_done);
1006 
1007         if (ctx->pkt_eos) {
1008             mpp_log("dec stream finish\n");
1009             break;
1010         }
1011     }
1012     mpp_log("rc2_pre_dec_thread exit");
1013     return NULL;
1014 }
1015 
mpi_rc_codec(MpiRc2TestCtx * ctx)1016 static MPP_RET mpi_rc_codec(MpiRc2TestCtx *ctx)
1017 {
1018     MPP_RET ret = MPP_OK;
1019     RK_S64 t_e;
1020 
1021     CHECK_RET(mpi_rc_buffer_init(ctx));
1022     CHECK_RET(mpi_rc_post_dec_init(ctx));
1023     CHECK_RET(mpi_rc_pre_dec_init(ctx));
1024     CHECK_RET(mpp_enc_cfg_init(&ctx->cfg));
1025     CHECK_RET(mpi_rc_enc_init(ctx));
1026 
1027     pthread_create(&ctx->dec_thr, NULL, rc2_pre_dec_thread, ctx);
1028 
1029     while (1) {
1030         mpi_rc_enc(ctx);
1031         if (ctx->enc_pkt_eos) {
1032             mpp_log("stream finish\n");
1033             break;
1034         }
1035     }
1036 
1037     t_e = mpp_time();
1038     RK_U64 elapsed_time = t_e - ctx->start_enc;
1039     float  frame_rate = (float)ctx->frm_idx * 1000000 / elapsed_time;
1040     mpp_log("enc_dec %d frame use time %lld ms frm rate %.2f\n",
1041             ctx->frm_idx, elapsed_time / 1000, frame_rate);
1042 
1043     if (ctx->frm_idx) {
1044         MpiEncTestArgs* enc_cmd = ctx->enc_cmd;
1045 
1046         mpp_log("%s: %s: average: bps %d | psnr %5.2f | ssim %5.5f",
1047                 enc_cmd->file_input, enc_cmd->gop_mode ? "smart_p" : "normal_p",
1048                 30 * (RK_U32)(ctx->total_bits / ctx->frm_idx),
1049                 ctx->total_psnrs / ctx->frm_idx, ctx->total_ssims / ctx->frm_idx);
1050         if (ctx->file.fp_stat)
1051             fprintf(ctx->file.fp_stat, "%s: %s: average: bps %dk | psnr %5.2f | ssim %5.5f \n",
1052                     enc_cmd->file_input, enc_cmd->gop_mode ? "smart_p" : "normal_p",
1053                     30 * (RK_U32)(ctx->total_bits / ctx->frm_idx) / 1000,
1054                     ctx->total_psnrs / ctx->frm_idx, ctx->total_ssims / ctx->frm_idx);
1055     }
1056 
1057     CHECK_RET(ctx->enc_mpi->reset(ctx->enc_ctx));
1058     CHECK_RET(ctx->dec_mpi_pre->reset(ctx->dec_ctx_pre));
1059     CHECK_RET(ctx->dec_mpi_post->reset(ctx->dec_ctx_post));
1060 
1061 MPP_TEST_OUT:
1062     // encoder deinit
1063 
1064     pthread_join(ctx->dec_thr, NULL);
1065 
1066     if (ctx->enc_ctx) {
1067         mpp_destroy(ctx->enc_ctx);
1068         ctx->enc_ctx = NULL;
1069     }
1070 
1071     if (ctx->pkt_grp) {
1072         mpp_buffer_group_put(ctx->pkt_grp);
1073         ctx->pkt_grp = NULL;
1074     }
1075 
1076     // decoder deinit
1077     if (ctx->dec_pkt_post) {
1078         mpp_packet_deinit(&ctx->dec_pkt_post);
1079         ctx->dec_pkt_post = NULL;
1080     }
1081 
1082     if (ctx->dec_pkt_pre) {
1083         mpp_packet_deinit(&ctx->dec_pkt_pre);
1084         ctx->dec_pkt_pre = NULL;
1085     }
1086 
1087     if (ctx->cfg) {
1088         mpp_enc_cfg_deinit(ctx->cfg);
1089         ctx->cfg = NULL;
1090     }
1091 
1092     if (ctx->dec_ctx_post) {
1093         mpp_destroy(ctx->dec_ctx_post);
1094         ctx->dec_ctx_post = NULL;
1095     }
1096 
1097     if (ctx->dec_ctx_pre) {
1098         mpp_destroy(ctx->dec_ctx_pre);
1099         ctx->dec_ctx_pre = NULL;
1100     }
1101 
1102     MPP_FREE(ctx->dec_in_buf_post);
1103     MPP_FREE(ctx->dec_in_buf_pre);
1104 
1105     return ret;
1106 }
1107 
main(int argc,char ** argv)1108 int main(int argc, char **argv)
1109 {
1110     MpiEncTestArgs* enc_cmd = mpi_enc_test_cmd_get();
1111     MpiRc2TestCtx *ctx = NULL;
1112     MPP_RET ret = MPP_OK;
1113 
1114     ret = mpi_enc_test_cmd_update_by_args(enc_cmd, argc, argv);
1115     if (ret)
1116         goto DONE;
1117 
1118     mpi_enc_test_cmd_show_opt(enc_cmd);
1119 
1120     ctx = mpp_calloc(MpiRc2TestCtx, 1);
1121     if (NULL == ctx) {
1122         ret = MPP_ERR_MALLOC;
1123         goto DONE;
1124     }
1125 
1126     ctx->enc_cmd = enc_cmd;
1127 
1128     ret = mpi_rc_init(ctx);
1129     if (ret) {
1130         mpp_err("mpi_rc_init failded ret %d", ret);
1131         goto DONE;
1132     }
1133 
1134     ret = mpi_rc_codec(ctx);
1135     if (ret)
1136         mpp_err("mpi_rc_codec failded ret %d", ret);
1137 
1138 DONE:
1139     if (ctx) {
1140         mpi_rc_deinit(ctx);
1141         ctx = NULL;
1142     }
1143 
1144     mpi_enc_test_cmd_put(enc_cmd);
1145 
1146     return (int)ret;
1147 }
1148