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