xref: /OK3568_Linux_fs/external/mpp/utils/mpi_enc_utils.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2015 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_enc_utils"
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <string.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #include "mpp_mem.h"
22*4882a593Smuzhiyun #include "mpp_debug.h"
23*4882a593Smuzhiyun #include "mpp_buffer.h"
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include "rk_mpi.h"
26*4882a593Smuzhiyun #include "utils.h"
27*4882a593Smuzhiyun #include "mpp_common.h"
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #include "mpp_opt.h"
30*4882a593Smuzhiyun #include "mpi_enc_utils.h"
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define MAX_FILE_NAME_LENGTH        256
33*4882a593Smuzhiyun 
mpi_enc_width_default_stride(RK_S32 width,MppFrameFormat fmt)34*4882a593Smuzhiyun RK_S32 mpi_enc_width_default_stride(RK_S32 width, MppFrameFormat fmt)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun     RK_S32 stride = 0;
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun     switch (fmt & MPP_FRAME_FMT_MASK) {
39*4882a593Smuzhiyun     case MPP_FMT_YUV420SP :
40*4882a593Smuzhiyun     case MPP_FMT_YUV420SP_VU : {
41*4882a593Smuzhiyun         stride = MPP_ALIGN(width, 8);
42*4882a593Smuzhiyun     } break;
43*4882a593Smuzhiyun     case MPP_FMT_YUV420P : {
44*4882a593Smuzhiyun         /* NOTE: 420P need to align to 16 so chroma can align to 8 */
45*4882a593Smuzhiyun         stride = MPP_ALIGN(width, 16);
46*4882a593Smuzhiyun     } break;
47*4882a593Smuzhiyun     case MPP_FMT_YUV422P:
48*4882a593Smuzhiyun     case MPP_FMT_YUV422SP:
49*4882a593Smuzhiyun     case MPP_FMT_YUV422SP_VU: {
50*4882a593Smuzhiyun         /* NOTE: 422 need to align to 8 so chroma can align to 16 */
51*4882a593Smuzhiyun         stride = MPP_ALIGN(width, 8);
52*4882a593Smuzhiyun     } break;
53*4882a593Smuzhiyun     case MPP_FMT_YUV444SP :
54*4882a593Smuzhiyun     case MPP_FMT_YUV444P : {
55*4882a593Smuzhiyun         stride = MPP_ALIGN(width, 8);
56*4882a593Smuzhiyun     } break;
57*4882a593Smuzhiyun     case MPP_FMT_RGB565:
58*4882a593Smuzhiyun     case MPP_FMT_BGR565:
59*4882a593Smuzhiyun     case MPP_FMT_RGB555:
60*4882a593Smuzhiyun     case MPP_FMT_BGR555:
61*4882a593Smuzhiyun     case MPP_FMT_RGB444:
62*4882a593Smuzhiyun     case MPP_FMT_BGR444:
63*4882a593Smuzhiyun     case MPP_FMT_YUV422_YUYV :
64*4882a593Smuzhiyun     case MPP_FMT_YUV422_YVYU :
65*4882a593Smuzhiyun     case MPP_FMT_YUV422_UYVY :
66*4882a593Smuzhiyun     case MPP_FMT_YUV422_VYUY : {
67*4882a593Smuzhiyun         /* NOTE: for vepu limitation */
68*4882a593Smuzhiyun         stride = MPP_ALIGN(width, 8) * 2;
69*4882a593Smuzhiyun     } break;
70*4882a593Smuzhiyun     case MPP_FMT_RGB888 :
71*4882a593Smuzhiyun     case MPP_FMT_BGR888 : {
72*4882a593Smuzhiyun         /* NOTE: for vepu limitation */
73*4882a593Smuzhiyun         stride = MPP_ALIGN(width, 8) * 3;
74*4882a593Smuzhiyun     } break;
75*4882a593Smuzhiyun     case MPP_FMT_RGB101010 :
76*4882a593Smuzhiyun     case MPP_FMT_BGR101010 :
77*4882a593Smuzhiyun     case MPP_FMT_ARGB8888 :
78*4882a593Smuzhiyun     case MPP_FMT_ABGR8888 :
79*4882a593Smuzhiyun     case MPP_FMT_BGRA8888 :
80*4882a593Smuzhiyun     case MPP_FMT_RGBA8888 : {
81*4882a593Smuzhiyun         /* NOTE: for vepu limitation */
82*4882a593Smuzhiyun         stride = MPP_ALIGN(width, 8) * 4;
83*4882a593Smuzhiyun     } break;
84*4882a593Smuzhiyun     default : {
85*4882a593Smuzhiyun         mpp_err_f("do not support type %d\n", fmt);
86*4882a593Smuzhiyun     } break;
87*4882a593Smuzhiyun     }
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun     return stride;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
mpi_enc_test_cmd_get(void)92*4882a593Smuzhiyun MpiEncTestArgs *mpi_enc_test_cmd_get(void)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun     MpiEncTestArgs *args = mpp_calloc(MpiEncTestArgs, 1);
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun     if (args)
97*4882a593Smuzhiyun         args->nthreads = 1;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun     return args;
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
mpi_enc_opt_i(void * ctx,const char * next)102*4882a593Smuzhiyun RK_S32 mpi_enc_opt_i(void *ctx, const char *next)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun     if (next) {
107*4882a593Smuzhiyun         size_t len = strnlen(next, MAX_FILE_NAME_LENGTH);
108*4882a593Smuzhiyun         if (len) {
109*4882a593Smuzhiyun             cmd->file_input = mpp_calloc(char, len + 1);
110*4882a593Smuzhiyun             strcpy(cmd->file_input, next);
111*4882a593Smuzhiyun             name_to_frame_format(cmd->file_input, &cmd->format);
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun             if (cmd->type_src == MPP_VIDEO_CodingUnused)
114*4882a593Smuzhiyun                 name_to_coding_type(cmd->file_input, &cmd->type_src);
115*4882a593Smuzhiyun         }
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun         return 1;
118*4882a593Smuzhiyun     }
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun     mpp_err("input file is invalid\n");
121*4882a593Smuzhiyun     return 0;
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun 
mpi_enc_opt_o(void * ctx,const char * next)124*4882a593Smuzhiyun RK_S32 mpi_enc_opt_o(void *ctx, const char *next)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun     if (next) {
129*4882a593Smuzhiyun         size_t len = strnlen(next, MAX_FILE_NAME_LENGTH);
130*4882a593Smuzhiyun         if (len) {
131*4882a593Smuzhiyun             cmd->file_output = mpp_calloc(char, len + 1);
132*4882a593Smuzhiyun             strcpy(cmd->file_output, next);
133*4882a593Smuzhiyun             name_to_coding_type(cmd->file_output, &cmd->type);
134*4882a593Smuzhiyun         }
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun         return 1;
137*4882a593Smuzhiyun     }
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun     mpp_log("output file is invalid\n");
140*4882a593Smuzhiyun     return 0;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
mpi_enc_opt_w(void * ctx,const char * next)143*4882a593Smuzhiyun RK_S32 mpi_enc_opt_w(void *ctx, const char *next)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun     if (next) {
148*4882a593Smuzhiyun         cmd->width = atoi(next);
149*4882a593Smuzhiyun         return 1;
150*4882a593Smuzhiyun     }
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun     mpp_err("invalid input width\n");
153*4882a593Smuzhiyun     return 0;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
mpi_enc_opt_h(void * ctx,const char * next)156*4882a593Smuzhiyun RK_S32 mpi_enc_opt_h(void *ctx, const char *next)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun     if (next) {
161*4882a593Smuzhiyun         cmd->height = atoi(next);
162*4882a593Smuzhiyun         return 1;
163*4882a593Smuzhiyun     }
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun     mpp_err("invalid input height\n");
166*4882a593Smuzhiyun     return 0;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun 
mpi_enc_opt_hstride(void * ctx,const char * next)169*4882a593Smuzhiyun RK_S32 mpi_enc_opt_hstride(void *ctx, const char *next)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun     if (next) {
174*4882a593Smuzhiyun         cmd->hor_stride = atoi(next);
175*4882a593Smuzhiyun         return 1;
176*4882a593Smuzhiyun     }
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun     mpp_err("invalid input horizontal stride\n");
179*4882a593Smuzhiyun     return 0;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun 
mpi_enc_opt_vstride(void * ctx,const char * next)182*4882a593Smuzhiyun RK_S32 mpi_enc_opt_vstride(void *ctx, const char *next)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun     if (next) {
187*4882a593Smuzhiyun         cmd->ver_stride = atoi(next);
188*4882a593Smuzhiyun         return 1;
189*4882a593Smuzhiyun     }
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun     mpp_err("invalid input vertical stride\n");
192*4882a593Smuzhiyun     return 0;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
mpi_enc_opt_f(void * ctx,const char * next)195*4882a593Smuzhiyun RK_S32 mpi_enc_opt_f(void *ctx, const char *next)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
198*4882a593Smuzhiyun     MppFrameFormat format = MPP_FMT_BUTT;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun     if (next) {
201*4882a593Smuzhiyun         if (strstr(next, "x") || strstr(next, "X")) {
202*4882a593Smuzhiyun             /* hex value with 0x prefix, use sscanf */
203*4882a593Smuzhiyun             sscanf(next, "0x%x", &format);
204*4882a593Smuzhiyun         } else if (strstr(next, "a") || strstr(next, "A") ||
205*4882a593Smuzhiyun                    strstr(next, "b") || strstr(next, "B") ||
206*4882a593Smuzhiyun                    strstr(next, "c") || strstr(next, "C") ||
207*4882a593Smuzhiyun                    strstr(next, "d") || strstr(next, "D") ||
208*4882a593Smuzhiyun                    strstr(next, "e") || strstr(next, "E") ||
209*4882a593Smuzhiyun                    strstr(next, "f") || strstr(next, "F")) {
210*4882a593Smuzhiyun             /* hex value without 0x prefix, use sscanf */
211*4882a593Smuzhiyun             sscanf(next, "%x", &format);
212*4882a593Smuzhiyun         } else {
213*4882a593Smuzhiyun             /* decimal value, use atoi */
214*4882a593Smuzhiyun             format = (MppFrameFormat)atoi(next);
215*4882a593Smuzhiyun         }
216*4882a593Smuzhiyun         if (MPP_FRAME_FMT_IS_BE(format) &&
217*4882a593Smuzhiyun             (MPP_FRAME_FMT_IS_YUV(format) || MPP_FRAME_FMT_IS_RGB(format))) {
218*4882a593Smuzhiyun             cmd->format = format;
219*4882a593Smuzhiyun             return 1;
220*4882a593Smuzhiyun         }
221*4882a593Smuzhiyun     }
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun     mpp_err("invalid input format %x\n", format);
224*4882a593Smuzhiyun     cmd->format = MPP_FMT_YUV420SP;
225*4882a593Smuzhiyun     return 0;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun 
mpi_enc_opt_t(void * ctx,const char * next)228*4882a593Smuzhiyun RK_S32 mpi_enc_opt_t(void *ctx, const char *next)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
231*4882a593Smuzhiyun     MppCodingType type = MPP_VIDEO_CodingUnused;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun     if (next) {
234*4882a593Smuzhiyun         type = (MppCodingType)atoi(next);
235*4882a593Smuzhiyun         if (!mpp_check_support_format(MPP_CTX_ENC, type))
236*4882a593Smuzhiyun             cmd->type = type;
237*4882a593Smuzhiyun         return 1;
238*4882a593Smuzhiyun     }
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun     mpp_err("invalid input coding type %d\n", type);
241*4882a593Smuzhiyun     return 0;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
mpi_enc_opt_tsrc(void * ctx,const char * next)244*4882a593Smuzhiyun RK_S32 mpi_enc_opt_tsrc(void *ctx, const char *next)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
247*4882a593Smuzhiyun     MppCodingType type = MPP_VIDEO_CodingUnused;
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun     if (next) {
250*4882a593Smuzhiyun         type = (MppCodingType)atoi(next);
251*4882a593Smuzhiyun         if (!mpp_check_support_format(MPP_CTX_DEC, type))
252*4882a593Smuzhiyun             cmd->type_src = type;
253*4882a593Smuzhiyun         return 1;
254*4882a593Smuzhiyun     }
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun     mpp_err("invalid input coding type %d\n", type);
257*4882a593Smuzhiyun     return 0;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 
mpi_enc_opt_n(void * ctx,const char * next)261*4882a593Smuzhiyun RK_S32 mpi_enc_opt_n(void *ctx, const char *next)
262*4882a593Smuzhiyun {
263*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun     if (next) {
266*4882a593Smuzhiyun         cmd->frame_num = atoi(next);
267*4882a593Smuzhiyun         return 1;
268*4882a593Smuzhiyun     }
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun     mpp_err("invalid input max number of frames\n");
271*4882a593Smuzhiyun     return 0;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun 
mpi_enc_opt_g(void * ctx,const char * next)274*4882a593Smuzhiyun RK_S32 mpi_enc_opt_g(void *ctx, const char *next)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
277*4882a593Smuzhiyun     RK_S32 cnt = 0;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun     if (next) {
280*4882a593Smuzhiyun         cnt = sscanf(next, "%d:%d:%d",
281*4882a593Smuzhiyun                      &cmd->gop_mode, &cmd->gop_len, &cmd->vi_len);
282*4882a593Smuzhiyun         if (cnt)
283*4882a593Smuzhiyun             return 1;
284*4882a593Smuzhiyun     }
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun     mpp_err("invalid gop mode use -g gop_mode:gop_len:vi_len\n");
287*4882a593Smuzhiyun     return 0;
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun 
mpi_enc_opt_rc(void * ctx,const char * next)290*4882a593Smuzhiyun RK_S32 mpi_enc_opt_rc(void *ctx, const char *next)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
293*4882a593Smuzhiyun     RK_S32 cnt = 0;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun     if (next) {
296*4882a593Smuzhiyun         cnt = sscanf(next, "%d", &cmd->rc_mode);
297*4882a593Smuzhiyun         if (cnt)
298*4882a593Smuzhiyun             return 1;
299*4882a593Smuzhiyun     }
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun     mpp_err("invalid rate control usage -rc rc_mode\n");
302*4882a593Smuzhiyun     mpp_err("rc_mode 0:vbr 1:cbr 2:avbr 3:cvbr 4:fixqp\n");
303*4882a593Smuzhiyun     return 0;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun 
mpi_enc_opt_bps(void * ctx,const char * next)306*4882a593Smuzhiyun RK_S32 mpi_enc_opt_bps(void *ctx, const char *next)
307*4882a593Smuzhiyun {
308*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
309*4882a593Smuzhiyun     RK_S32 cnt = 0;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun     if (next) {
312*4882a593Smuzhiyun         cnt = sscanf(next, "%d:%d:%d",
313*4882a593Smuzhiyun                      &cmd->bps_target, &cmd->bps_min, &cmd->bps_max);
314*4882a593Smuzhiyun         if (cnt)
315*4882a593Smuzhiyun             return 1;
316*4882a593Smuzhiyun     }
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun     mpp_err("invalid bit rate usage -bps bps_target:bps_min:bps_max\n");
319*4882a593Smuzhiyun     return 0;
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun 
mpi_enc_opt_fps(void * ctx,const char * next)322*4882a593Smuzhiyun RK_S32 mpi_enc_opt_fps(void *ctx, const char *next)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun     if (next) {
327*4882a593Smuzhiyun         RK_U32 num = sscanf(next, "%d:%d:%d/%d:%d:%d",
328*4882a593Smuzhiyun                             &cmd->fps_in_num, &cmd->fps_in_den, &cmd->fps_in_flex,
329*4882a593Smuzhiyun                             &cmd->fps_out_num, &cmd->fps_out_den, &cmd->fps_out_flex);
330*4882a593Smuzhiyun         switch (num) {
331*4882a593Smuzhiyun         case 1 : {
332*4882a593Smuzhiyun             cmd->fps_out_num = cmd->fps_in_num;
333*4882a593Smuzhiyun             cmd->fps_out_den = cmd->fps_in_den = 1;
334*4882a593Smuzhiyun             cmd->fps_out_flex = cmd->fps_in_flex = 0;
335*4882a593Smuzhiyun         } break;
336*4882a593Smuzhiyun         case 2 : {
337*4882a593Smuzhiyun             cmd->fps_out_num = cmd->fps_in_num;
338*4882a593Smuzhiyun             cmd->fps_out_den = cmd->fps_in_den;
339*4882a593Smuzhiyun             cmd->fps_out_flex = cmd->fps_in_flex = 0;
340*4882a593Smuzhiyun         } break;
341*4882a593Smuzhiyun         case 3 : {
342*4882a593Smuzhiyun             cmd->fps_out_num = cmd->fps_in_num;
343*4882a593Smuzhiyun             cmd->fps_out_den = cmd->fps_in_den;
344*4882a593Smuzhiyun             cmd->fps_out_flex = cmd->fps_in_flex;
345*4882a593Smuzhiyun         } break;
346*4882a593Smuzhiyun         case 4 : {
347*4882a593Smuzhiyun             cmd->fps_out_den = 1;
348*4882a593Smuzhiyun             cmd->fps_out_flex = 0;
349*4882a593Smuzhiyun         } break;
350*4882a593Smuzhiyun         case 5 : {
351*4882a593Smuzhiyun             cmd->fps_out_flex = 0;
352*4882a593Smuzhiyun         } break;
353*4882a593Smuzhiyun         case 6 : {
354*4882a593Smuzhiyun         } break;
355*4882a593Smuzhiyun         default : {
356*4882a593Smuzhiyun             mpp_err("invalid in/out frame rate,"
357*4882a593Smuzhiyun                     " use \"-fps numerator:denominator:flex\""
358*4882a593Smuzhiyun                     " for set the input to the same fps as the output, such as 50:1:1\n"
359*4882a593Smuzhiyun                     " or \"-fps numerator:denominator:flex/numerator:denominator:flex\""
360*4882a593Smuzhiyun                     " for set input and output separately, such as 40:1:1/30:1:0\n");
361*4882a593Smuzhiyun         } break;
362*4882a593Smuzhiyun         }
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun         return (num && num <= 6);
365*4882a593Smuzhiyun     }
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun     mpp_err("invalid output frame rate\n");
368*4882a593Smuzhiyun     return 0;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun 
mpi_enc_opt_qc(void * ctx,const char * next)371*4882a593Smuzhiyun RK_S32 mpi_enc_opt_qc(void *ctx, const char *next)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
374*4882a593Smuzhiyun     RK_S32 cnt = 0;
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun     if (next) {
377*4882a593Smuzhiyun         cnt = sscanf(next, "%d:%d:%d:%d:%d", &cmd->qp_init,
378*4882a593Smuzhiyun                      &cmd->qp_min, &cmd->qp_max, &cmd->qp_min_i, &cmd->qp_max_i);
379*4882a593Smuzhiyun         if (cnt)
380*4882a593Smuzhiyun             return 1;
381*4882a593Smuzhiyun     }
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun     mpp_err("invalid quality control usage -qc qp_init:min:max:min_i:max_i\n");
384*4882a593Smuzhiyun     return 0;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun 
mpi_enc_opt_s(void * ctx,const char * next)387*4882a593Smuzhiyun RK_S32 mpi_enc_opt_s(void *ctx, const char *next)
388*4882a593Smuzhiyun {
389*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun     cmd->nthreads = -1;
392*4882a593Smuzhiyun     if (next) {
393*4882a593Smuzhiyun         cmd->nthreads = atoi(next);
394*4882a593Smuzhiyun         if (cmd->nthreads >= 1)
395*4882a593Smuzhiyun             return 1;
396*4882a593Smuzhiyun     }
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun     mpp_err("invalid nthreads %d\n", cmd->nthreads);
399*4882a593Smuzhiyun     cmd->nthreads = 1;
400*4882a593Smuzhiyun     return 0;
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun 
mpi_enc_opt_l(void * ctx,const char * next)403*4882a593Smuzhiyun RK_S32 mpi_enc_opt_l(void *ctx, const char *next)
404*4882a593Smuzhiyun {
405*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun     if (next) {
408*4882a593Smuzhiyun         cmd->loop_cnt = atoi(next);
409*4882a593Smuzhiyun         return 1;
410*4882a593Smuzhiyun     }
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun     mpp_err("invalid loop count\n");
413*4882a593Smuzhiyun     return 0;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun 
mpi_enc_opt_v(void * ctx,const char * next)416*4882a593Smuzhiyun RK_S32 mpi_enc_opt_v(void *ctx, const char *next)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun     if (next) {
421*4882a593Smuzhiyun         if (strstr(next, "q"))
422*4882a593Smuzhiyun             cmd->quiet = 1;
423*4882a593Smuzhiyun         if (strstr(next, "f"))
424*4882a593Smuzhiyun             cmd->trace_fps = 1;
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun         return 1;
427*4882a593Smuzhiyun     }
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun     return 0;
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun 
mpi_enc_opt_ini(void * ctx,const char * next)432*4882a593Smuzhiyun RK_S32 mpi_enc_opt_ini(void *ctx, const char *next)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun     if (next) {
437*4882a593Smuzhiyun         size_t len = strnlen(next, MAX_FILE_NAME_LENGTH);
438*4882a593Smuzhiyun         if (len) {
439*4882a593Smuzhiyun             cmd->file_cfg = mpp_calloc(char, len + 1);
440*4882a593Smuzhiyun             strncpy(cmd->file_cfg, next, len);
441*4882a593Smuzhiyun             cmd->cfg_ini = iniparser_load(cmd->file_cfg);
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun             return 1;
444*4882a593Smuzhiyun         }
445*4882a593Smuzhiyun     }
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun     mpp_err("input ini file is invalid\n");
448*4882a593Smuzhiyun     return 0;
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun 
mpi_enc_opt_slt(void * ctx,const char * next)451*4882a593Smuzhiyun RK_S32 mpi_enc_opt_slt(void *ctx, const char *next)
452*4882a593Smuzhiyun {
453*4882a593Smuzhiyun     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun     if (next) {
456*4882a593Smuzhiyun         size_t len = strnlen(next, MAX_FILE_NAME_LENGTH);
457*4882a593Smuzhiyun         if (len) {
458*4882a593Smuzhiyun             cmd->file_slt = mpp_calloc(char, len + 1);
459*4882a593Smuzhiyun             strncpy(cmd->file_slt, next, len);
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun             return 1;
462*4882a593Smuzhiyun         }
463*4882a593Smuzhiyun     }
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun     mpp_err("input slt verify file is invalid\n");
466*4882a593Smuzhiyun     return 0;
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun 
mpi_enc_opt_help(void * ctx,const char * next)469*4882a593Smuzhiyun RK_S32 mpi_enc_opt_help(void *ctx, const char *next)
470*4882a593Smuzhiyun {
471*4882a593Smuzhiyun     (void)ctx;
472*4882a593Smuzhiyun     (void)next;
473*4882a593Smuzhiyun     return -1;
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun static MppOptInfo enc_opts[] = {
477*4882a593Smuzhiyun     {"i",       "input_file",           "input frame file",                         mpi_enc_opt_i},
478*4882a593Smuzhiyun     {"o",       "output_file",          "output encoded bitstream file",            mpi_enc_opt_o},
479*4882a593Smuzhiyun     {"w",       "width",                "the width of input picture",               mpi_enc_opt_w},
480*4882a593Smuzhiyun     {"h",       "height",               "the height of input picture",              mpi_enc_opt_h},
481*4882a593Smuzhiyun     {"hstride", "hor_stride",           "the horizontal stride of input picture",   mpi_enc_opt_hstride},
482*4882a593Smuzhiyun     {"vstride", "ver_stride",           "the vertical stride of input picture",     mpi_enc_opt_vstride},
483*4882a593Smuzhiyun     {"f",       "format",               "the format of input picture",              mpi_enc_opt_f},
484*4882a593Smuzhiyun     {"t",       "type",                 "output stream coding type",                mpi_enc_opt_t},
485*4882a593Smuzhiyun     {"tsrc",    "source type",          "input file source coding type",            mpi_enc_opt_tsrc},
486*4882a593Smuzhiyun     {"n",       "max frame number",     "max encoding frame number",                mpi_enc_opt_n},
487*4882a593Smuzhiyun     {"g",       "gop reference mode",   "gop_mode:gop_len:vi_len",                  mpi_enc_opt_g},
488*4882a593Smuzhiyun     {"rc",      "rate control mode",    "set rc_mode, 0:vbr 1:cbr 2:fixqp 3:avbr",  mpi_enc_opt_rc},
489*4882a593Smuzhiyun     {"bps",     "bps target:min:max",   "set tareget:min:max bps",                  mpi_enc_opt_bps},
490*4882a593Smuzhiyun     {"fps",     "in/output fps",        "set input and output frame rate",          mpi_enc_opt_fps},
491*4882a593Smuzhiyun     {"qc",      "quality control",      "set qp_init:min:max:min_i:max_i",          mpi_enc_opt_qc},
492*4882a593Smuzhiyun     {"s",       "instance_nb",          "number of instances",                      mpi_enc_opt_s},
493*4882a593Smuzhiyun     {"v",       "trace option",         "q - quiet f - show fps",                   mpi_enc_opt_v},
494*4882a593Smuzhiyun     {"l",       "loop count",           "loop encoding times for each frame",       mpi_enc_opt_l},
495*4882a593Smuzhiyun     {"ini",     "ini file",             "encoder extra ini config file",            mpi_enc_opt_ini},
496*4882a593Smuzhiyun     {"slt",     "slt file",             "slt verify data file",                     mpi_enc_opt_slt},
497*4882a593Smuzhiyun };
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun static RK_U32 enc_opt_cnt = MPP_ARRAY_ELEMS(enc_opts);
500*4882a593Smuzhiyun 
mpi_enc_show_help(const char * name)501*4882a593Smuzhiyun RK_S32 mpi_enc_show_help(const char *name)
502*4882a593Smuzhiyun {
503*4882a593Smuzhiyun     RK_U32 max_name = 1;
504*4882a593Smuzhiyun     RK_U32 max_full_name = 1;
505*4882a593Smuzhiyun     RK_U32 max_help = 1;
506*4882a593Smuzhiyun     char logs[256];
507*4882a593Smuzhiyun     RK_U32 len;
508*4882a593Smuzhiyun     RK_U32 i;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun     mpp_log("usage: %s [options]\n", name);
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun     for (i = 0; i < enc_opt_cnt; i++) {
513*4882a593Smuzhiyun         MppOptInfo *opt = &enc_opts[i];
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun         if (opt->name) {
516*4882a593Smuzhiyun             len = strlen(opt->name);
517*4882a593Smuzhiyun             if (len > max_name)
518*4882a593Smuzhiyun                 max_name = len;
519*4882a593Smuzhiyun         }
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun         if (opt->full_name) {
522*4882a593Smuzhiyun             len = strlen(opt->full_name);
523*4882a593Smuzhiyun             if (len > max_full_name)
524*4882a593Smuzhiyun                 max_full_name = len;
525*4882a593Smuzhiyun         }
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun         if (opt->help) {
528*4882a593Smuzhiyun             len = strlen(opt->help);
529*4882a593Smuzhiyun             if (len > max_help)
530*4882a593Smuzhiyun                 max_help = len;
531*4882a593Smuzhiyun         }
532*4882a593Smuzhiyun     }
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun     snprintf(logs, sizeof(logs) - 1, "-%%-%ds %%-%ds %%-%ds\n", max_name, max_full_name, max_help);
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun     for (i = 0; i < enc_opt_cnt; i++) {
537*4882a593Smuzhiyun         MppOptInfo *opt = &enc_opts[i];
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun         mpp_log(logs, opt->name, opt->full_name, opt->help);
540*4882a593Smuzhiyun     }
541*4882a593Smuzhiyun     mpp_show_support_format();
542*4882a593Smuzhiyun     mpp_show_color_format();
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun     return -1;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun 
show_enc_fps(RK_S64 total_time,RK_S64 total_count,RK_S64 last_time,RK_S64 last_count)547*4882a593Smuzhiyun void show_enc_fps(RK_S64 total_time, RK_S64 total_count, RK_S64 last_time, RK_S64 last_count)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun     float avg_fps = (float)total_count * 1000000 / total_time;
550*4882a593Smuzhiyun     float ins_fps = (float)last_count * 1000000 / last_time;
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun     mpp_log("encoded %10lld frame fps avg %7.2f ins %7.2f\n",
553*4882a593Smuzhiyun             total_count, avg_fps, ins_fps);
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun 
mpi_enc_test_cmd_update_by_args(MpiEncTestArgs * cmd,int argc,char ** argv)556*4882a593Smuzhiyun MPP_RET mpi_enc_test_cmd_update_by_args(MpiEncTestArgs* cmd, int argc, char **argv)
557*4882a593Smuzhiyun {
558*4882a593Smuzhiyun     MppOpt opts = NULL;
559*4882a593Smuzhiyun     RK_S32 ret = -1;
560*4882a593Smuzhiyun     RK_U32 i;
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun     if ((argc < 2) || NULL == cmd || NULL == argv)
563*4882a593Smuzhiyun         goto done;
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun     cmd->rc_mode = MPP_ENC_RC_MODE_BUTT;
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun     mpp_opt_init(&opts);
568*4882a593Smuzhiyun     /* should change node count when option increases */
569*4882a593Smuzhiyun     mpp_opt_setup(opts, cmd, 67, enc_opt_cnt);
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun     for (i = 0; i < enc_opt_cnt; i++)
572*4882a593Smuzhiyun         mpp_opt_add(opts, &enc_opts[i]);
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun     /* mark option end */
575*4882a593Smuzhiyun     mpp_opt_add(opts, NULL);
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun     ret = mpp_opt_parse(opts, argc, argv);
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun     /* check essential parameter */
580*4882a593Smuzhiyun     if (cmd->type <= MPP_VIDEO_CodingAutoDetect) {
581*4882a593Smuzhiyun         mpp_err("invalid type %d\n", cmd->type);
582*4882a593Smuzhiyun         ret = MPP_NOK;
583*4882a593Smuzhiyun     }
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun     if (cmd->rc_mode == MPP_ENC_RC_MODE_BUTT)
586*4882a593Smuzhiyun         cmd->rc_mode = (cmd->type == MPP_VIDEO_CodingMJPEG) ?
587*4882a593Smuzhiyun                        MPP_ENC_RC_MODE_FIXQP : MPP_ENC_RC_MODE_VBR;
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun     if (!cmd->hor_stride)
590*4882a593Smuzhiyun         cmd->hor_stride = mpi_enc_width_default_stride(cmd->width, cmd->format);
591*4882a593Smuzhiyun     if (!cmd->ver_stride)
592*4882a593Smuzhiyun         cmd->ver_stride = cmd->height;
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun     if (cmd->type_src == MPP_VIDEO_CodingUnused) {
595*4882a593Smuzhiyun         if (cmd->width <= 0 || cmd->height <= 0 ||
596*4882a593Smuzhiyun             cmd->hor_stride <= 0 || cmd->ver_stride <= 0) {
597*4882a593Smuzhiyun             mpp_err("invalid w:h [%d:%d] stride [%d:%d]\n",
598*4882a593Smuzhiyun                     cmd->width, cmd->height, cmd->hor_stride, cmd->ver_stride);
599*4882a593Smuzhiyun             ret = MPP_NOK;
600*4882a593Smuzhiyun         }
601*4882a593Smuzhiyun     }
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun     if (cmd->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
604*4882a593Smuzhiyun         if (!cmd->qp_init) {
605*4882a593Smuzhiyun             if (cmd->type == MPP_VIDEO_CodingAVC ||
606*4882a593Smuzhiyun                 cmd->type == MPP_VIDEO_CodingHEVC)
607*4882a593Smuzhiyun                 cmd->qp_init = 26;
608*4882a593Smuzhiyun         }
609*4882a593Smuzhiyun     }
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun     if (cmd->trace_fps) {
612*4882a593Smuzhiyun         fps_calc_init(&cmd->fps);
613*4882a593Smuzhiyun         mpp_assert(cmd->fps);
614*4882a593Smuzhiyun         fps_calc_set_cb(cmd->fps, show_enc_fps);
615*4882a593Smuzhiyun     }
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun done:
618*4882a593Smuzhiyun     if (opts) {
619*4882a593Smuzhiyun         mpp_opt_deinit(opts);
620*4882a593Smuzhiyun         opts = NULL;
621*4882a593Smuzhiyun     }
622*4882a593Smuzhiyun     if (ret)
623*4882a593Smuzhiyun         mpi_enc_show_help(argv[0]);
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun     return ret;
626*4882a593Smuzhiyun }
627*4882a593Smuzhiyun 
mpi_enc_test_cmd_put(MpiEncTestArgs * cmd)628*4882a593Smuzhiyun MPP_RET mpi_enc_test_cmd_put(MpiEncTestArgs* cmd)
629*4882a593Smuzhiyun {
630*4882a593Smuzhiyun     if (NULL == cmd)
631*4882a593Smuzhiyun         return MPP_OK;
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun     if (cmd->cfg_ini) {
634*4882a593Smuzhiyun         iniparser_freedict(cmd->cfg_ini);
635*4882a593Smuzhiyun         cmd->cfg_ini = NULL;
636*4882a593Smuzhiyun     }
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun     if (cmd->fps) {
639*4882a593Smuzhiyun         fps_calc_deinit(cmd->fps);
640*4882a593Smuzhiyun         cmd->fps = NULL;
641*4882a593Smuzhiyun     }
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun     MPP_FREE(cmd->file_input);
644*4882a593Smuzhiyun     MPP_FREE(cmd->file_output);
645*4882a593Smuzhiyun     MPP_FREE(cmd->file_cfg);
646*4882a593Smuzhiyun     MPP_FREE(cmd->file_slt);
647*4882a593Smuzhiyun     MPP_FREE(cmd);
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun     return MPP_OK;
650*4882a593Smuzhiyun }
651*4882a593Smuzhiyun 
mpi_enc_gen_ref_cfg(MppEncRefCfg ref,RK_S32 gop_mode)652*4882a593Smuzhiyun MPP_RET mpi_enc_gen_ref_cfg(MppEncRefCfg ref, RK_S32 gop_mode)
653*4882a593Smuzhiyun {
654*4882a593Smuzhiyun     MppEncRefLtFrmCfg lt_ref[4];
655*4882a593Smuzhiyun     MppEncRefStFrmCfg st_ref[16];
656*4882a593Smuzhiyun     RK_S32 lt_cnt = 0;
657*4882a593Smuzhiyun     RK_S32 st_cnt = 0;
658*4882a593Smuzhiyun     MPP_RET ret = MPP_OK;
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun     memset(&lt_ref, 0, sizeof(lt_ref));
661*4882a593Smuzhiyun     memset(&st_ref, 0, sizeof(st_ref));
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun     switch (gop_mode) {
664*4882a593Smuzhiyun     case 3 : {
665*4882a593Smuzhiyun         // tsvc4
666*4882a593Smuzhiyun         //      /-> P1      /-> P3        /-> P5      /-> P7
667*4882a593Smuzhiyun         //     /           /             /           /
668*4882a593Smuzhiyun         //    //--------> P2            //--------> P6
669*4882a593Smuzhiyun         //   //                        //
670*4882a593Smuzhiyun         //  ///---------------------> P4
671*4882a593Smuzhiyun         // ///
672*4882a593Smuzhiyun         // P0 ------------------------------------------------> P8
673*4882a593Smuzhiyun         lt_cnt = 1;
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun         /* set 8 frame lt-ref gap */
676*4882a593Smuzhiyun         lt_ref[0].lt_idx        = 0;
677*4882a593Smuzhiyun         lt_ref[0].temporal_id   = 0;
678*4882a593Smuzhiyun         lt_ref[0].ref_mode      = REF_TO_PREV_LT_REF;
679*4882a593Smuzhiyun         lt_ref[0].lt_gap        = 8;
680*4882a593Smuzhiyun         lt_ref[0].lt_delay      = 0;
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun         st_cnt = 9;
683*4882a593Smuzhiyun         /* set tsvc4 st-ref struct */
684*4882a593Smuzhiyun         /* st 0 layer 0 - ref */
685*4882a593Smuzhiyun         st_ref[0].is_non_ref    = 0;
686*4882a593Smuzhiyun         st_ref[0].temporal_id   = 0;
687*4882a593Smuzhiyun         st_ref[0].ref_mode      = REF_TO_TEMPORAL_LAYER;
688*4882a593Smuzhiyun         st_ref[0].ref_arg       = 0;
689*4882a593Smuzhiyun         st_ref[0].repeat        = 0;
690*4882a593Smuzhiyun         /* st 1 layer 3 - non-ref */
691*4882a593Smuzhiyun         st_ref[1].is_non_ref    = 1;
692*4882a593Smuzhiyun         st_ref[1].temporal_id   = 3;
693*4882a593Smuzhiyun         st_ref[1].ref_mode      = REF_TO_PREV_REF_FRM;
694*4882a593Smuzhiyun         st_ref[1].ref_arg       = 0;
695*4882a593Smuzhiyun         st_ref[1].repeat        = 0;
696*4882a593Smuzhiyun         /* st 2 layer 2 - ref */
697*4882a593Smuzhiyun         st_ref[2].is_non_ref    = 0;
698*4882a593Smuzhiyun         st_ref[2].temporal_id   = 2;
699*4882a593Smuzhiyun         st_ref[2].ref_mode      = REF_TO_PREV_REF_FRM;
700*4882a593Smuzhiyun         st_ref[2].ref_arg       = 0;
701*4882a593Smuzhiyun         st_ref[2].repeat        = 0;
702*4882a593Smuzhiyun         /* st 3 layer 3 - non-ref */
703*4882a593Smuzhiyun         st_ref[3].is_non_ref    = 1;
704*4882a593Smuzhiyun         st_ref[3].temporal_id   = 3;
705*4882a593Smuzhiyun         st_ref[3].ref_mode      = REF_TO_PREV_REF_FRM;
706*4882a593Smuzhiyun         st_ref[3].ref_arg       = 0;
707*4882a593Smuzhiyun         st_ref[3].repeat        = 0;
708*4882a593Smuzhiyun         /* st 4 layer 1 - ref */
709*4882a593Smuzhiyun         st_ref[4].is_non_ref    = 0;
710*4882a593Smuzhiyun         st_ref[4].temporal_id   = 1;
711*4882a593Smuzhiyun         st_ref[4].ref_mode      = REF_TO_PREV_LT_REF;
712*4882a593Smuzhiyun         st_ref[4].ref_arg       = 0;
713*4882a593Smuzhiyun         st_ref[4].repeat        = 0;
714*4882a593Smuzhiyun         /* st 5 layer 3 - non-ref */
715*4882a593Smuzhiyun         st_ref[5].is_non_ref    = 1;
716*4882a593Smuzhiyun         st_ref[5].temporal_id   = 3;
717*4882a593Smuzhiyun         st_ref[5].ref_mode      = REF_TO_PREV_REF_FRM;
718*4882a593Smuzhiyun         st_ref[5].ref_arg       = 0;
719*4882a593Smuzhiyun         st_ref[5].repeat        = 0;
720*4882a593Smuzhiyun         /* st 6 layer 2 - ref */
721*4882a593Smuzhiyun         st_ref[6].is_non_ref    = 0;
722*4882a593Smuzhiyun         st_ref[6].temporal_id   = 2;
723*4882a593Smuzhiyun         st_ref[6].ref_mode      = REF_TO_PREV_REF_FRM;
724*4882a593Smuzhiyun         st_ref[6].ref_arg       = 0;
725*4882a593Smuzhiyun         st_ref[6].repeat        = 0;
726*4882a593Smuzhiyun         /* st 7 layer 3 - non-ref */
727*4882a593Smuzhiyun         st_ref[7].is_non_ref    = 1;
728*4882a593Smuzhiyun         st_ref[7].temporal_id   = 3;
729*4882a593Smuzhiyun         st_ref[7].ref_mode      = REF_TO_PREV_REF_FRM;
730*4882a593Smuzhiyun         st_ref[7].ref_arg       = 0;
731*4882a593Smuzhiyun         st_ref[7].repeat        = 0;
732*4882a593Smuzhiyun         /* st 8 layer 0 - ref */
733*4882a593Smuzhiyun         st_ref[8].is_non_ref    = 0;
734*4882a593Smuzhiyun         st_ref[8].temporal_id   = 0;
735*4882a593Smuzhiyun         st_ref[8].ref_mode      = REF_TO_TEMPORAL_LAYER;
736*4882a593Smuzhiyun         st_ref[8].ref_arg       = 0;
737*4882a593Smuzhiyun         st_ref[8].repeat        = 0;
738*4882a593Smuzhiyun     } break;
739*4882a593Smuzhiyun     case 2 : {
740*4882a593Smuzhiyun         // tsvc3
741*4882a593Smuzhiyun         //     /-> P1      /-> P3
742*4882a593Smuzhiyun         //    /           /
743*4882a593Smuzhiyun         //   //--------> P2
744*4882a593Smuzhiyun         //  //
745*4882a593Smuzhiyun         // P0/---------------------> P4
746*4882a593Smuzhiyun         lt_cnt = 0;
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun         st_cnt = 5;
749*4882a593Smuzhiyun         /* set tsvc4 st-ref struct */
750*4882a593Smuzhiyun         /* st 0 layer 0 - ref */
751*4882a593Smuzhiyun         st_ref[0].is_non_ref    = 0;
752*4882a593Smuzhiyun         st_ref[0].temporal_id   = 0;
753*4882a593Smuzhiyun         st_ref[0].ref_mode      = REF_TO_TEMPORAL_LAYER;
754*4882a593Smuzhiyun         st_ref[0].ref_arg       = 0;
755*4882a593Smuzhiyun         st_ref[0].repeat        = 0;
756*4882a593Smuzhiyun         /* st 1 layer 2 - non-ref */
757*4882a593Smuzhiyun         st_ref[1].is_non_ref    = 1;
758*4882a593Smuzhiyun         st_ref[1].temporal_id   = 2;
759*4882a593Smuzhiyun         st_ref[1].ref_mode      = REF_TO_PREV_REF_FRM;
760*4882a593Smuzhiyun         st_ref[1].ref_arg       = 0;
761*4882a593Smuzhiyun         st_ref[1].repeat        = 0;
762*4882a593Smuzhiyun         /* st 2 layer 1 - ref */
763*4882a593Smuzhiyun         st_ref[2].is_non_ref    = 0;
764*4882a593Smuzhiyun         st_ref[2].temporal_id   = 1;
765*4882a593Smuzhiyun         st_ref[2].ref_mode      = REF_TO_PREV_REF_FRM;
766*4882a593Smuzhiyun         st_ref[2].ref_arg       = 0;
767*4882a593Smuzhiyun         st_ref[2].repeat        = 0;
768*4882a593Smuzhiyun         /* st 3 layer 2 - non-ref */
769*4882a593Smuzhiyun         st_ref[3].is_non_ref    = 1;
770*4882a593Smuzhiyun         st_ref[3].temporal_id   = 2;
771*4882a593Smuzhiyun         st_ref[3].ref_mode      = REF_TO_PREV_REF_FRM;
772*4882a593Smuzhiyun         st_ref[3].ref_arg       = 0;
773*4882a593Smuzhiyun         st_ref[3].repeat        = 0;
774*4882a593Smuzhiyun         /* st 4 layer 0 - ref */
775*4882a593Smuzhiyun         st_ref[4].is_non_ref    = 0;
776*4882a593Smuzhiyun         st_ref[4].temporal_id   = 0;
777*4882a593Smuzhiyun         st_ref[4].ref_mode      = REF_TO_TEMPORAL_LAYER;
778*4882a593Smuzhiyun         st_ref[4].ref_arg       = 0;
779*4882a593Smuzhiyun         st_ref[4].repeat        = 0;
780*4882a593Smuzhiyun     } break;
781*4882a593Smuzhiyun     case 1 : {
782*4882a593Smuzhiyun         // tsvc2
783*4882a593Smuzhiyun         //   /-> P1
784*4882a593Smuzhiyun         //  /
785*4882a593Smuzhiyun         // P0--------> P2
786*4882a593Smuzhiyun         lt_cnt = 0;
787*4882a593Smuzhiyun 
788*4882a593Smuzhiyun         st_cnt = 3;
789*4882a593Smuzhiyun         /* set tsvc4 st-ref struct */
790*4882a593Smuzhiyun         /* st 0 layer 0 - ref */
791*4882a593Smuzhiyun         st_ref[0].is_non_ref    = 0;
792*4882a593Smuzhiyun         st_ref[0].temporal_id   = 0;
793*4882a593Smuzhiyun         st_ref[0].ref_mode      = REF_TO_TEMPORAL_LAYER;
794*4882a593Smuzhiyun         st_ref[0].ref_arg       = 0;
795*4882a593Smuzhiyun         st_ref[0].repeat        = 0;
796*4882a593Smuzhiyun         /* st 1 layer 2 - non-ref */
797*4882a593Smuzhiyun         st_ref[1].is_non_ref    = 1;
798*4882a593Smuzhiyun         st_ref[1].temporal_id   = 1;
799*4882a593Smuzhiyun         st_ref[1].ref_mode      = REF_TO_PREV_REF_FRM;
800*4882a593Smuzhiyun         st_ref[1].ref_arg       = 0;
801*4882a593Smuzhiyun         st_ref[1].repeat        = 0;
802*4882a593Smuzhiyun         /* st 2 layer 1 - ref */
803*4882a593Smuzhiyun         st_ref[2].is_non_ref    = 0;
804*4882a593Smuzhiyun         st_ref[2].temporal_id   = 0;
805*4882a593Smuzhiyun         st_ref[2].ref_mode      = REF_TO_PREV_REF_FRM;
806*4882a593Smuzhiyun         st_ref[2].ref_arg       = 0;
807*4882a593Smuzhiyun         st_ref[2].repeat        = 0;
808*4882a593Smuzhiyun     } break;
809*4882a593Smuzhiyun     default : {
810*4882a593Smuzhiyun         mpp_err_f("unsupport gop mode %d\n", gop_mode);
811*4882a593Smuzhiyun     } break;
812*4882a593Smuzhiyun     }
813*4882a593Smuzhiyun 
814*4882a593Smuzhiyun     if (lt_cnt || st_cnt) {
815*4882a593Smuzhiyun         ret = mpp_enc_ref_cfg_set_cfg_cnt(ref, lt_cnt, st_cnt);
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun         if (lt_cnt)
818*4882a593Smuzhiyun             ret = mpp_enc_ref_cfg_add_lt_cfg(ref, lt_cnt, lt_ref);
819*4882a593Smuzhiyun 
820*4882a593Smuzhiyun         if (st_cnt)
821*4882a593Smuzhiyun             ret = mpp_enc_ref_cfg_add_st_cfg(ref, st_cnt, st_ref);
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun         /* check and get dpb size */
824*4882a593Smuzhiyun         ret = mpp_enc_ref_cfg_check(ref);
825*4882a593Smuzhiyun     }
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun     return ret;
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun 
mpi_enc_gen_smart_gop_ref_cfg(MppEncRefCfg ref,RK_S32 gop_len,RK_S32 vi_len)830*4882a593Smuzhiyun MPP_RET mpi_enc_gen_smart_gop_ref_cfg(MppEncRefCfg ref, RK_S32 gop_len, RK_S32 vi_len)
831*4882a593Smuzhiyun {
832*4882a593Smuzhiyun     MppEncRefLtFrmCfg lt_ref[4];
833*4882a593Smuzhiyun     MppEncRefStFrmCfg st_ref[16];
834*4882a593Smuzhiyun     RK_S32 lt_cnt = 1;
835*4882a593Smuzhiyun     RK_S32 st_cnt = 8;
836*4882a593Smuzhiyun     RK_S32 pos = 0;
837*4882a593Smuzhiyun     MPP_RET ret = MPP_OK;
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun     memset(&lt_ref, 0, sizeof(lt_ref));
840*4882a593Smuzhiyun     memset(&st_ref, 0, sizeof(st_ref));
841*4882a593Smuzhiyun 
842*4882a593Smuzhiyun     ret = mpp_enc_ref_cfg_set_cfg_cnt(ref, lt_cnt, st_cnt);
843*4882a593Smuzhiyun 
844*4882a593Smuzhiyun     /* set 8 frame lt-ref gap */
845*4882a593Smuzhiyun     lt_ref[0].lt_idx        = 0;
846*4882a593Smuzhiyun     lt_ref[0].temporal_id   = 0;
847*4882a593Smuzhiyun     lt_ref[0].ref_mode      = REF_TO_PREV_LT_REF;
848*4882a593Smuzhiyun     lt_ref[0].lt_gap        = gop_len;
849*4882a593Smuzhiyun     lt_ref[0].lt_delay      = 0;
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun     ret = mpp_enc_ref_cfg_add_lt_cfg(ref, 1, lt_ref);
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun     /* st 0 layer 0 - ref */
854*4882a593Smuzhiyun     st_ref[pos].is_non_ref  = 0;
855*4882a593Smuzhiyun     st_ref[pos].temporal_id = 0;
856*4882a593Smuzhiyun     st_ref[pos].ref_mode    = REF_TO_PREV_INTRA;
857*4882a593Smuzhiyun     st_ref[pos].ref_arg     = 0;
858*4882a593Smuzhiyun     st_ref[pos].repeat      = 0;
859*4882a593Smuzhiyun     pos++;
860*4882a593Smuzhiyun 
861*4882a593Smuzhiyun     /* st 1 layer 1 - non-ref */
862*4882a593Smuzhiyun     if (vi_len > 1) {
863*4882a593Smuzhiyun         st_ref[pos].is_non_ref  = 0;
864*4882a593Smuzhiyun         st_ref[pos].temporal_id = 1;
865*4882a593Smuzhiyun         st_ref[pos].ref_mode    = REF_TO_PREV_REF_FRM;
866*4882a593Smuzhiyun         st_ref[pos].ref_arg     = 0;
867*4882a593Smuzhiyun         st_ref[pos].repeat      = vi_len - 2;
868*4882a593Smuzhiyun         pos++;
869*4882a593Smuzhiyun     }
870*4882a593Smuzhiyun 
871*4882a593Smuzhiyun     st_ref[pos].is_non_ref  = 0;
872*4882a593Smuzhiyun     st_ref[pos].temporal_id = 0;
873*4882a593Smuzhiyun     st_ref[pos].ref_mode    = REF_TO_PREV_INTRA;
874*4882a593Smuzhiyun     st_ref[pos].ref_arg     = 0;
875*4882a593Smuzhiyun     st_ref[pos].repeat      = 0;
876*4882a593Smuzhiyun     pos++;
877*4882a593Smuzhiyun 
878*4882a593Smuzhiyun     ret = mpp_enc_ref_cfg_add_st_cfg(ref, pos, st_ref);
879*4882a593Smuzhiyun 
880*4882a593Smuzhiyun     /* check and get dpb size */
881*4882a593Smuzhiyun     ret = mpp_enc_ref_cfg_check(ref);
882*4882a593Smuzhiyun 
883*4882a593Smuzhiyun     return ret;
884*4882a593Smuzhiyun }
885*4882a593Smuzhiyun 
mpi_enc_gen_osd_plt(MppEncOSDPlt * osd_plt,RK_U32 frame_cnt)886*4882a593Smuzhiyun MPP_RET mpi_enc_gen_osd_plt(MppEncOSDPlt *osd_plt, RK_U32 frame_cnt)
887*4882a593Smuzhiyun {
888*4882a593Smuzhiyun     /*
889*4882a593Smuzhiyun      * osd idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes).
890*4882a593Smuzhiyun      * for general use, 1/8 Y buffer is enough.
891*4882a593Smuzhiyun      */
892*4882a593Smuzhiyun     static RK_U32 plt_table[8] = {
893*4882a593Smuzhiyun         MPP_ENC_OSD_PLT_RED,
894*4882a593Smuzhiyun         MPP_ENC_OSD_PLT_YELLOW,
895*4882a593Smuzhiyun         MPP_ENC_OSD_PLT_BLUE,
896*4882a593Smuzhiyun         MPP_ENC_OSD_PLT_GREEN,
897*4882a593Smuzhiyun         MPP_ENC_OSD_PLT_CYAN,
898*4882a593Smuzhiyun         MPP_ENC_OSD_PLT_TRANS,
899*4882a593Smuzhiyun         MPP_ENC_OSD_PLT_BLACK,
900*4882a593Smuzhiyun         MPP_ENC_OSD_PLT_WHITE,
901*4882a593Smuzhiyun     };
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun     if (osd_plt) {
904*4882a593Smuzhiyun         RK_U32 k = 0;
905*4882a593Smuzhiyun         RK_U32 base = frame_cnt & 7;
906*4882a593Smuzhiyun 
907*4882a593Smuzhiyun         for (k = 0; k < 256; k++)
908*4882a593Smuzhiyun             osd_plt->data[k].val = plt_table[(base + k) % 8];
909*4882a593Smuzhiyun     }
910*4882a593Smuzhiyun     return MPP_OK;
911*4882a593Smuzhiyun }
912*4882a593Smuzhiyun 
mpi_enc_gen_osd_data(MppEncOSDData * osd_data,MppBufferGroup group,RK_U32 width,RK_U32 height,RK_U32 frame_cnt)913*4882a593Smuzhiyun MPP_RET mpi_enc_gen_osd_data(MppEncOSDData *osd_data, MppBufferGroup group,
914*4882a593Smuzhiyun                              RK_U32 width, RK_U32 height, RK_U32 frame_cnt)
915*4882a593Smuzhiyun {
916*4882a593Smuzhiyun     MppEncOSDRegion *region = NULL;
917*4882a593Smuzhiyun     RK_U32 k = 0;
918*4882a593Smuzhiyun     RK_U32 num_region = 8;
919*4882a593Smuzhiyun     RK_U32 buf_offset = 0;
920*4882a593Smuzhiyun     RK_U32 buf_size = 0;
921*4882a593Smuzhiyun     RK_U32 mb_w_max = MPP_ALIGN(width, 16) / 16;
922*4882a593Smuzhiyun     RK_U32 mb_h_max = MPP_ALIGN(height, 16) / 16;
923*4882a593Smuzhiyun     RK_U32 step_x = MPP_ALIGN(mb_w_max, 8) / 8;
924*4882a593Smuzhiyun     RK_U32 step_y = MPP_ALIGN(mb_h_max, 16) / 16;
925*4882a593Smuzhiyun     RK_U32 mb_x = (frame_cnt * step_x) % mb_w_max;
926*4882a593Smuzhiyun     RK_U32 mb_y = (frame_cnt * step_y) % mb_h_max;
927*4882a593Smuzhiyun     RK_U32 mb_w = step_x;
928*4882a593Smuzhiyun     RK_U32 mb_h = step_y;
929*4882a593Smuzhiyun     MppBuffer buf = osd_data->buf;
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun     if (buf)
932*4882a593Smuzhiyun         buf_size = mpp_buffer_get_size(buf);
933*4882a593Smuzhiyun 
934*4882a593Smuzhiyun     /* generate osd region info */
935*4882a593Smuzhiyun     osd_data->num_region = num_region;
936*4882a593Smuzhiyun 
937*4882a593Smuzhiyun     region = osd_data->region;
938*4882a593Smuzhiyun 
939*4882a593Smuzhiyun     for (k = 0; k < num_region; k++, region++) {
940*4882a593Smuzhiyun         // NOTE: offset must be 16 byte aligned
941*4882a593Smuzhiyun         RK_U32 region_size = MPP_ALIGN(mb_w * mb_h * 256, 16);
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun         region->inverse = 1;
944*4882a593Smuzhiyun         region->start_mb_x = mb_x;
945*4882a593Smuzhiyun         region->start_mb_y = mb_y;
946*4882a593Smuzhiyun         region->num_mb_x = mb_w;
947*4882a593Smuzhiyun         region->num_mb_y = mb_h;
948*4882a593Smuzhiyun         region->buf_offset = buf_offset;
949*4882a593Smuzhiyun         region->enable = (mb_w && mb_h);
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun         buf_offset += region_size;
952*4882a593Smuzhiyun 
953*4882a593Smuzhiyun         mb_x += step_x;
954*4882a593Smuzhiyun         mb_y += step_y;
955*4882a593Smuzhiyun         if (mb_x >= mb_w_max)
956*4882a593Smuzhiyun             mb_x -= mb_w_max;
957*4882a593Smuzhiyun         if (mb_y >= mb_h_max)
958*4882a593Smuzhiyun             mb_y -= mb_h_max;
959*4882a593Smuzhiyun     }
960*4882a593Smuzhiyun 
961*4882a593Smuzhiyun     /* create buffer and write osd index data */
962*4882a593Smuzhiyun     if (buf_size < buf_offset) {
963*4882a593Smuzhiyun         if (buf)
964*4882a593Smuzhiyun             mpp_buffer_put(buf);
965*4882a593Smuzhiyun 
966*4882a593Smuzhiyun         mpp_buffer_get(group, &buf, buf_offset);
967*4882a593Smuzhiyun         if (NULL == buf)
968*4882a593Smuzhiyun             mpp_err_f("failed to create osd buffer size %d\n", buf_offset);
969*4882a593Smuzhiyun     }
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun     if (buf) {
972*4882a593Smuzhiyun         void *ptr = mpp_buffer_get_ptr(buf);
973*4882a593Smuzhiyun         region = osd_data->region;
974*4882a593Smuzhiyun 
975*4882a593Smuzhiyun         for (k = 0; k < num_region; k++, region++) {
976*4882a593Smuzhiyun             mb_w = region->num_mb_x;
977*4882a593Smuzhiyun             mb_h = region->num_mb_y;
978*4882a593Smuzhiyun             buf_offset = region->buf_offset;
979*4882a593Smuzhiyun 
980*4882a593Smuzhiyun             memset(ptr + buf_offset, k, mb_w * mb_h * 256);
981*4882a593Smuzhiyun         }
982*4882a593Smuzhiyun     }
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun     osd_data->buf = buf;
985*4882a593Smuzhiyun 
986*4882a593Smuzhiyun     return MPP_OK;
987*4882a593Smuzhiyun }
988*4882a593Smuzhiyun 
mpi_enc_test_cmd_show_opt(MpiEncTestArgs * cmd)989*4882a593Smuzhiyun MPP_RET mpi_enc_test_cmd_show_opt(MpiEncTestArgs* cmd)
990*4882a593Smuzhiyun {
991*4882a593Smuzhiyun     mpp_log("cmd parse result:\n");
992*4882a593Smuzhiyun     mpp_log("input  file name: %s\n", cmd->file_input);
993*4882a593Smuzhiyun     mpp_log("output file name: %s\n", cmd->file_output);
994*4882a593Smuzhiyun     mpp_log("width      : %d\n", cmd->width);
995*4882a593Smuzhiyun     mpp_log("height     : %d\n", cmd->height);
996*4882a593Smuzhiyun     mpp_log("format     : %d\n", cmd->format);
997*4882a593Smuzhiyun     mpp_log("type       : %d\n", cmd->type);
998*4882a593Smuzhiyun     if (cmd->file_slt)
999*4882a593Smuzhiyun         mpp_log("verify     : %s\n", cmd->file_slt);
1000*4882a593Smuzhiyun 
1001*4882a593Smuzhiyun     return MPP_OK;
1002*4882a593Smuzhiyun }
1003