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