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