xref: /rockchip-linux_mpp/utils/mpi_enc_utils.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /*
2  * Copyright 2015 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define MODULE_TAG "mpi_enc_utils"
18 
19 #include <string.h>
20 
21 #include "mpp_mem.h"
22 #include "mpp_debug.h"
23 #include "mpp_buffer.h"
24 
25 #include "rk_mpi.h"
26 #include "utils.h"
27 #include "mpp_common.h"
28 
29 #include "mpp_opt.h"
30 #include "mpi_enc_utils.h"
31 
32 #define MAX_FILE_NAME_LENGTH        256
33 
mpi_enc_width_default_stride(RK_S32 width,MppFrameFormat fmt)34 RK_S32 mpi_enc_width_default_stride(RK_S32 width, MppFrameFormat fmt)
35 {
36     RK_S32 stride = 0;
37 
38     switch (fmt & MPP_FRAME_FMT_MASK) {
39     case MPP_FMT_YUV400 :
40     case MPP_FMT_YUV420SP :
41     case MPP_FMT_YUV420SP_VU : {
42         stride = MPP_ALIGN(width, 8);
43     } break;
44     case MPP_FMT_YUV420P : {
45         /* NOTE: 420P need to align to 16 so chroma can align to 8 */
46         stride = MPP_ALIGN(width, 16);
47     } break;
48     case MPP_FMT_YUV422P:
49     case MPP_FMT_YUV422SP:
50     case MPP_FMT_YUV422SP_VU: {
51         /* NOTE: 422 need to align to 8 so chroma can align to 16 */
52         stride = MPP_ALIGN(width, 8);
53     } break;
54     case MPP_FMT_YUV444SP :
55     case MPP_FMT_YUV444P : {
56         stride = MPP_ALIGN(width, 8);
57     } break;
58     case MPP_FMT_RGB565:
59     case MPP_FMT_BGR565:
60     case MPP_FMT_RGB555:
61     case MPP_FMT_BGR555:
62     case MPP_FMT_RGB444:
63     case MPP_FMT_BGR444:
64     case MPP_FMT_YUV422_YUYV :
65     case MPP_FMT_YUV422_YVYU :
66     case MPP_FMT_YUV422_UYVY :
67     case MPP_FMT_YUV422_VYUY : {
68         /* NOTE: for vepu limitation */
69         stride = MPP_ALIGN(width, 8) * 2;
70     } break;
71     case MPP_FMT_RGB888 :
72     case MPP_FMT_BGR888 : {
73         /* NOTE: for vepu limitation */
74         stride = MPP_ALIGN(width, 8) * 3;
75     } break;
76     case MPP_FMT_RGB101010 :
77     case MPP_FMT_BGR101010 :
78     case MPP_FMT_ARGB8888 :
79     case MPP_FMT_ABGR8888 :
80     case MPP_FMT_BGRA8888 :
81     case MPP_FMT_RGBA8888 : {
82         /* NOTE: for vepu limitation */
83         stride = MPP_ALIGN(width, 8) * 4;
84     } break;
85     default : {
86         mpp_err_f("do not support type %d\n", fmt);
87     } break;
88     }
89 
90     return stride;
91 }
92 
mpi_enc_test_cmd_get(void)93 MpiEncTestArgs *mpi_enc_test_cmd_get(void)
94 {
95     MpiEncTestArgs *args = mpp_calloc(MpiEncTestArgs, 1);
96 
97     if (args) {
98         args->nthreads = 1;
99         args->frm_step = 1;
100     }
101 
102     return args;
103 }
104 
mpi_enc_opt_i(void * ctx,const char * next)105 RK_S32 mpi_enc_opt_i(void *ctx, const char *next)
106 {
107     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
108 
109     if (next) {
110         size_t len = strnlen(next, MAX_FILE_NAME_LENGTH);
111         if (len) {
112             cmd->file_input = mpp_calloc(char, len + 1);
113             strcpy(cmd->file_input, next);
114             name_to_frame_format(cmd->file_input, &cmd->format);
115 
116             if (cmd->type_src == MPP_VIDEO_CodingUnused)
117                 name_to_coding_type(cmd->file_input, &cmd->type_src);
118         }
119 
120         return 1;
121     }
122 
123     mpp_err("input file is invalid\n");
124     return 0;
125 }
126 
mpi_enc_opt_o(void * ctx,const char * next)127 RK_S32 mpi_enc_opt_o(void *ctx, const char *next)
128 {
129     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
130 
131     if (next) {
132         size_t len = strnlen(next, MAX_FILE_NAME_LENGTH);
133         if (len) {
134             cmd->file_output = mpp_calloc(char, len + 1);
135             strcpy(cmd->file_output, next);
136             name_to_coding_type(cmd->file_output, &cmd->type);
137         }
138 
139         return 1;
140     }
141 
142     mpp_log("output file is invalid\n");
143     return 0;
144 }
145 
mpi_enc_opt_w(void * ctx,const char * next)146 RK_S32 mpi_enc_opt_w(void *ctx, const char *next)
147 {
148     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
149 
150     if (next) {
151         cmd->width = atoi(next);
152         return 1;
153     }
154 
155     mpp_err("invalid input width\n");
156     return 0;
157 }
158 
mpi_enc_opt_h(void * ctx,const char * next)159 RK_S32 mpi_enc_opt_h(void *ctx, const char *next)
160 {
161     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
162 
163     if (next) {
164         cmd->height = atoi(next);
165         return 1;
166     }
167 
168     mpp_err("invalid input height\n");
169     return 0;
170 }
171 
mpi_enc_opt_hstride(void * ctx,const char * next)172 RK_S32 mpi_enc_opt_hstride(void *ctx, const char *next)
173 {
174     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
175 
176     if (next) {
177         cmd->hor_stride = atoi(next);
178         return 1;
179     }
180 
181     mpp_err("invalid input horizontal stride\n");
182     return 0;
183 }
184 
mpi_enc_opt_vstride(void * ctx,const char * next)185 RK_S32 mpi_enc_opt_vstride(void *ctx, const char *next)
186 {
187     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
188 
189     if (next) {
190         cmd->ver_stride = atoi(next);
191         return 1;
192     }
193 
194     mpp_err("invalid input vertical stride\n");
195     return 0;
196 }
197 
mpi_enc_opt_f(void * ctx,const char * next)198 RK_S32 mpi_enc_opt_f(void *ctx, const char *next)
199 {
200     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
201 
202     if (next) {
203         long number = 0;
204         MppFrameFormat format = MPP_FMT_BUTT;
205 
206         if (MPP_OK == str_to_frm_fmt(next, &number)) {
207             format = (MppFrameFormat)number;
208 
209             if (MPP_FRAME_FMT_IS_BE(format) &&
210                 (MPP_FRAME_FMT_IS_YUV(format) || MPP_FRAME_FMT_IS_RGB(format))) {
211                 cmd->format = format;
212                 return 1;
213             }
214 
215             mpp_err("invalid input format 0x%x\n", format);
216         }
217     }
218 
219     cmd->format = MPP_FMT_YUV420SP;
220     return 0;
221 }
222 
mpi_enc_opt_t(void * ctx,const char * next)223 RK_S32 mpi_enc_opt_t(void *ctx, const char *next)
224 {
225     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
226     MppCodingType type = MPP_VIDEO_CodingUnused;
227 
228     if (next) {
229         type = (MppCodingType)atoi(next);
230         if (!mpp_check_support_format(MPP_CTX_ENC, type))
231             cmd->type = type;
232         return 1;
233     }
234 
235     mpp_err("invalid input coding type %d\n", type);
236     return 0;
237 }
238 
mpi_enc_opt_tsrc(void * ctx,const char * next)239 RK_S32 mpi_enc_opt_tsrc(void *ctx, const char *next)
240 {
241     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
242     MppCodingType type = MPP_VIDEO_CodingUnused;
243 
244     if (next) {
245         type = (MppCodingType)atoi(next);
246         if (!mpp_check_support_format(MPP_CTX_DEC, type))
247             cmd->type_src = type;
248         return 1;
249     }
250 
251     mpp_err("invalid input coding type %d\n", type);
252     return 0;
253 }
254 
255 
mpi_enc_opt_n(void * ctx,const char * next)256 RK_S32 mpi_enc_opt_n(void *ctx, const char *next)
257 {
258     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
259 
260     if (next) {
261         cmd->frame_num = atoi(next);
262         return 1;
263     }
264 
265     mpp_err("invalid input max number of frames\n");
266     return 0;
267 }
268 
mpi_enc_opt_g(void * ctx,const char * next)269 RK_S32 mpi_enc_opt_g(void *ctx, const char *next)
270 {
271     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
272     RK_S32 cnt = 0;
273 
274     if (next) {
275         cnt = sscanf(next, "%d:%d:%d",
276                      &cmd->gop_mode, &cmd->gop_len, &cmd->vi_len);
277         if (cnt)
278             return 1;
279     }
280 
281     mpp_err("invalid gop mode use -g gop_mode:gop_len:vi_len\n");
282     return 0;
283 }
284 
mpi_enc_opt_rc(void * ctx,const char * next)285 RK_S32 mpi_enc_opt_rc(void *ctx, const char *next)
286 {
287     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
288     RK_S32 cnt = 0;
289 
290     if (next) {
291         cnt = sscanf(next, "%d", &cmd->rc_mode);
292         if (cnt)
293             return 1;
294     }
295 
296     mpp_err("invalid rate control usage -rc rc_mode\n");
297     mpp_err("rc_mode 0:vbr 1:cbr 2:fixqp 3:avbr 4:smtrc\n");
298     return 0;
299 }
300 
mpi_enc_opt_bps(void * ctx,const char * next)301 RK_S32 mpi_enc_opt_bps(void *ctx, const char *next)
302 {
303     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
304     RK_S32 cnt = 0;
305 
306     if (next) {
307         cnt = sscanf(next, "%d:%d:%d",
308                      &cmd->bps_target, &cmd->bps_min, &cmd->bps_max);
309         if (cnt)
310             return 1;
311     }
312 
313     mpp_err("invalid bit rate usage -bps bps_target:bps_min:bps_max\n");
314     return 0;
315 }
316 
mpi_enc_opt_fps(void * ctx,const char * next)317 RK_S32 mpi_enc_opt_fps(void *ctx, const char *next)
318 {
319     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
320 
321     if (next) {
322         RK_U32 num = sscanf(next, "%d:%d:%d/%d:%d:%d",
323                             &cmd->fps_in_num, &cmd->fps_in_den, &cmd->fps_in_flex,
324                             &cmd->fps_out_num, &cmd->fps_out_den, &cmd->fps_out_flex);
325         switch (num) {
326         case 1 : {
327             cmd->fps_out_num = cmd->fps_in_num;
328             cmd->fps_out_den = cmd->fps_in_den = 1;
329             cmd->fps_out_flex = cmd->fps_in_flex = 0;
330         } break;
331         case 2 : {
332             cmd->fps_out_num = cmd->fps_in_num;
333             cmd->fps_out_den = cmd->fps_in_den;
334             cmd->fps_out_flex = cmd->fps_in_flex = 0;
335         } break;
336         case 3 : {
337             cmd->fps_out_num = cmd->fps_in_num;
338             cmd->fps_out_den = cmd->fps_in_den;
339             cmd->fps_out_flex = cmd->fps_in_flex;
340         } break;
341         case 4 : {
342             cmd->fps_out_den = 1;
343             cmd->fps_out_flex = 0;
344         } break;
345         case 5 : {
346             cmd->fps_out_flex = 0;
347         } break;
348         case 6 : {
349         } break;
350         default : {
351             mpp_err("invalid in/out frame rate,"
352                     " use \"-fps numerator:denominator:flex\""
353                     " for set the input to the same fps as the output, such as 50:1:1\n"
354                     " or \"-fps numerator:denominator:flex/numerator:denominator:flex\""
355                     " for set input and output separately, such as 40:1:1/30:1:0\n");
356         } break;
357         }
358 
359         return (num && num <= 6);
360     }
361 
362     mpp_err("invalid output frame rate\n");
363     return 0;
364 }
365 
mpi_enc_opt_qc(void * ctx,const char * next)366 RK_S32 mpi_enc_opt_qc(void *ctx, const char *next)
367 {
368     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
369     RK_S32 cnt = 0;
370 
371     if (next) {
372         cnt = sscanf(next, "%d:%d:%d:%d:%d", &cmd->qp_init,
373                      &cmd->qp_min, &cmd->qp_max, &cmd->qp_min_i, &cmd->qp_max_i);
374         if (cnt)
375             return 1;
376     }
377 
378     mpp_err("invalid quality control usage -qc qp_init:min:max:min_i:max_i\n");
379     return 0;
380 }
381 
mpi_enc_opt_fqc(void * ctx,const char * next)382 RK_S32 mpi_enc_opt_fqc(void *ctx, const char *next)
383 {
384     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
385     RK_S32 cnt = 0;
386 
387     if (next) {
388         cnt = sscanf(next, "%d:%d:%d:%d", &cmd->fqp_min_i, &cmd->fqp_max_i,
389                      &cmd->fqp_min_p, &cmd->fqp_max_p);
390         if (cnt)
391             return 1;
392     }
393 
394     mpp_err("invalid frame quality control usage -fqc min_i:max_i:min_p:max_p\n");
395     return 0;
396 }
397 
mpi_enc_opt_s(void * ctx,const char * next)398 RK_S32 mpi_enc_opt_s(void *ctx, const char *next)
399 {
400     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
401 
402     cmd->nthreads = -1;
403     if (next) {
404         cmd->nthreads = atoi(next);
405         if (cmd->nthreads >= 1)
406             return 1;
407     }
408 
409     mpp_err("invalid nthreads %d\n", cmd->nthreads);
410     cmd->nthreads = 1;
411     return 0;
412 }
413 
mpi_enc_opt_l(void * ctx,const char * next)414 RK_S32 mpi_enc_opt_l(void *ctx, const char *next)
415 {
416     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
417 
418     if (next) {
419         cmd->loop_cnt = atoi(next);
420         return 1;
421     }
422 
423     mpp_err("invalid loop count\n");
424     return 0;
425 }
426 
mpi_enc_opt_v(void * ctx,const char * next)427 RK_S32 mpi_enc_opt_v(void *ctx, const char *next)
428 {
429     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
430 
431     if (next) {
432         if (strstr(next, "q"))
433             cmd->quiet = 1;
434         if (strstr(next, "f"))
435             cmd->trace_fps = 1;
436 
437         return 1;
438     }
439 
440     return 0;
441 }
442 
mpi_enc_opt_ini(void * ctx,const char * next)443 RK_S32 mpi_enc_opt_ini(void *ctx, const char *next)
444 {
445     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
446 
447     if (next) {
448         size_t len = strnlen(next, MAX_FILE_NAME_LENGTH);
449         if (len) {
450             cmd->file_cfg = mpp_calloc(char, len + 1);
451             strncpy(cmd->file_cfg, next, len);
452             cmd->cfg_ini = iniparser_load(cmd->file_cfg);
453 
454             return 1;
455         }
456     }
457 
458     mpp_err("input ini file is invalid\n");
459     return 0;
460 }
461 
mpi_enc_opt_slt(void * ctx,const char * next)462 RK_S32 mpi_enc_opt_slt(void *ctx, const char *next)
463 {
464     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
465 
466     if (next) {
467         size_t len = strnlen(next, MAX_FILE_NAME_LENGTH);
468         if (len) {
469             cmd->file_slt = mpp_calloc(char, len + 1);
470             strncpy(cmd->file_slt, next, len);
471 
472             return 1;
473         }
474     }
475 
476     mpp_err("input slt verify file is invalid\n");
477     return 0;
478 }
479 
mpi_enc_opt_step(void * ctx,const char * next)480 RK_S32 mpi_enc_opt_step(void *ctx, const char *next)
481 {
482     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
483 
484     if (next) {
485         cmd->frm_step = atoi(next);
486         return 1;
487     }
488 
489     mpp_err("invalid input frame step\n");
490     return 0;
491 }
492 
mpi_enc_opt_sm(void * ctx,const char * next)493 RK_S32 mpi_enc_opt_sm(void *ctx, const char *next)
494 {
495     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
496 
497     if (next) {
498         cmd->scene_mode = atoi(next);
499         return 1;
500     }
501 
502     mpp_err("invalid scene mode\n");
503     return 0;
504 }
505 
mpi_enc_opt_qpdd(void * ctx,const char * next)506 RK_S32 mpi_enc_opt_qpdd(void *ctx, const char *next)
507 {
508     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
509 
510     if (next) {
511         cmd->cu_qp_delta_depth = atoi(next);
512         return 1;
513     }
514 
515     mpp_err("invalid cu_qp_delta_depth\n");
516     return 0;
517 }
518 
mpi_enc_opt_dbe(void * ctx,const char * next)519 RK_S32 mpi_enc_opt_dbe(void *ctx, const char *next)
520 {
521     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
522 
523     if (next) {
524         cmd->deblur_en = atoi(next);
525         return 1;
526     }
527 
528     mpp_err("invalid deblur en\n");
529     return 0;
530 }
531 
mpi_enc_opt_dbs(void * ctx,const char * next)532 RK_S32 mpi_enc_opt_dbs(void *ctx, const char *next)
533 {
534     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
535 
536     if (next) {
537         cmd->deblur_str = atoi(next);
538         return 1;
539     }
540 
541     mpp_err("invalid deblur str\n");
542 
543     return 0;
544 }
545 
mpi_enc_opt_help(void * ctx,const char * next)546 RK_S32 mpi_enc_opt_help(void *ctx, const char *next)
547 {
548     (void)ctx;
549     (void)next;
550     return -1;
551 }
552 
mpi_enc_opt_atf(void * ctx,const char * next)553 RK_S32 mpi_enc_opt_atf(void *ctx, const char *next)
554 {
555     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
556 
557     if (next) {
558         RK_S32 val = atoi(next);
559 
560         if (val >= 0 && val <= 3 ) {
561             cmd->anti_flicker_str = val;
562             cmd->atf_str = val;
563         } else {
564             cmd->anti_flicker_str = 0;
565             cmd->atf_str = 0;
566             mpp_err("invalid atf_str %d set to default 0\n", val);
567         }
568         return 1;
569     }
570 
571     mpp_err("invalid cu_qp_delta_depth\n");
572     return 0;
573 }
574 
mpi_enc_opt_atl(void * ctx,const char * next)575 RK_S32 mpi_enc_opt_atl(void *ctx, const char *next)
576 {
577     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
578 
579     if (next) {
580         cmd->atl_str = atoi(next);
581         return 1;
582     }
583 
584     mpp_err("invalid atl_str\n");
585     return 0;
586 }
587 
mpi_enc_opt_atr_i(void * ctx,const char * next)588 RK_S32 mpi_enc_opt_atr_i(void *ctx, const char *next)
589 {
590     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
591 
592     if (next) {
593         cmd->atr_str_i = atoi(next);
594         return 1;
595     }
596 
597     mpp_err("invalid atr_str_i\n");
598     return 0;
599 }
600 
mpi_enc_opt_atr_p(void * ctx,const char * next)601 RK_S32 mpi_enc_opt_atr_p(void *ctx, const char *next)
602 {
603     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
604 
605     if (next) {
606         cmd->atr_str_p = atoi(next);
607         return 1;
608     }
609 
610     mpp_err("invalid atr_str_p\n");
611     return 0;
612 }
613 
mpi_enc_opt_sao_i(void * ctx,const char * next)614 RK_S32 mpi_enc_opt_sao_i(void *ctx, const char *next)
615 {
616     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
617 
618     if (next) {
619         cmd->sao_str_i = atoi(next);
620         return 1;
621     }
622 
623     mpp_err("invalid sao_str_i\n");
624     return 0;
625 }
626 
mpi_enc_opt_sao_p(void * ctx,const char * next)627 RK_S32 mpi_enc_opt_sao_p(void *ctx, const char *next)
628 {
629     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
630 
631     if (next) {
632         cmd->sao_str_p = atoi(next);
633         return 1;
634     }
635 
636     mpp_err("invalid sao_str_p\n");
637     return 0;
638 }
639 
mpi_enc_opt_bc(void * ctx,const char * next)640 RK_S32 mpi_enc_opt_bc(void *ctx, const char *next)
641 {
642     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
643 
644     if (next) {
645         cmd->rc_container = atoi(next);
646         return 1;
647     }
648 
649     mpp_err("invalid bitrate container\n");
650     return 0;
651 }
652 
mpi_enc_opt_bias_i(void * ctx,const char * next)653 RK_S32 mpi_enc_opt_bias_i(void *ctx, const char *next)
654 {
655     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
656 
657     if (next) {
658         cmd->bias_i = atoi(next);
659         return 1;
660     }
661 
662     mpp_err("invalid bias i\n");
663     return 0;
664 }
665 
mpi_enc_opt_bias_p(void * ctx,const char * next)666 RK_S32 mpi_enc_opt_bias_p(void *ctx, const char *next)
667 {
668     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
669 
670     if (next) {
671         cmd->bias_p = atoi(next);
672         return 1;
673     }
674 
675     mpp_err("invalid bias p\n");
676     return 0;
677 }
678 
mpi_enc_opt_lmd(void * ctx,const char * next)679 RK_S32 mpi_enc_opt_lmd(void *ctx, const char *next)
680 {
681     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
682 
683     if (next) {
684         cmd->lambda_idx_p = atoi(next);
685         return 1;
686     }
687 
688     mpp_err("invalid lambda idx\n");
689     return 0;
690 }
691 
mpi_enc_opt_lmdi(void * ctx,const char * next)692 RK_S32 mpi_enc_opt_lmdi(void *ctx, const char *next)
693 {
694     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
695 
696     if (next) {
697         cmd->lambda_idx_i = atoi(next);
698         return 1;
699     }
700 
701     mpp_err("invalid intra lambda idx\n");
702     return 0;
703 }
704 
mpi_enc_opt_speed(void * ctx,const char * next)705 RK_S32 mpi_enc_opt_speed(void *ctx, const char *next)
706 {
707     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
708 
709     if (next) {
710         cmd->speed = atoi(next);
711         if (cmd->speed > 3 || cmd->speed < 0) {
712             cmd->speed = 0;
713             mpp_err("invalid speed %d set to default 0\n", cmd->speed);
714         }
715         return 1;
716     }
717 
718     mpp_err("invalid speed mode\n");
719     return 0;
720 }
721 
mpi_enc_opt_kmpp(void * ctx,const char * next)722 RK_S32 mpi_enc_opt_kmpp(void *ctx, const char *next)
723 {
724     MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
725 
726     if (next) {
727         cmd->kmpp_en = atoi(next);
728         if (cmd->kmpp_en) {
729             if (access("/dev/vcodec", F_OK | R_OK | W_OK)) {
730                 mpp_err("failed to access /dev/vcodec, check kmpp devices\n");
731                 return -1;
732             }
733         }
734         return 1;
735     }
736 
737     mpp_err("invalid kmpp enable\n");
738     return 0;
739 }
740 
741 static MppOptInfo enc_opts[] = {
742     {"i",       "input_file",           "input frame file",                         mpi_enc_opt_i},
743     {"o",       "output_file",          "output encoded bitstream file",            mpi_enc_opt_o},
744     {"w",       "width",                "the width of input picture",               mpi_enc_opt_w},
745     {"h",       "height",               "the height of input picture",              mpi_enc_opt_h},
746     {"hstride", "hor_stride",           "the horizontal stride of input picture",   mpi_enc_opt_hstride},
747     {"vstride", "ver_stride",           "the vertical stride of input picture",     mpi_enc_opt_vstride},
748     {"f",       "format",               "the format of input picture",              mpi_enc_opt_f},
749     {"t",       "type",                 "output stream coding type",                mpi_enc_opt_t},
750     {"tsrc",    "source type",          "input file source coding type",            mpi_enc_opt_tsrc},
751     {"n",       "max frame number",     "max encoding frame number",                mpi_enc_opt_n},
752     {"g",       "gop reference mode",   "gop_mode:gop_len:vi_len",                  mpi_enc_opt_g},
753     {"rc",      "rate control mode",    "rc_mode, 0:vbr 1:cbr 2:fixqp 3:avbr 4:smtrc", mpi_enc_opt_rc},
754     {"bps",     "bps target:min:max",   "set tareget:min:max bps",                  mpi_enc_opt_bps},
755     {"fps",     "in/output fps",        "set input and output frame rate",          mpi_enc_opt_fps},
756     {"qc",      "quality control",      "set qp_init:min:max:min_i:max_i",          mpi_enc_opt_qc},
757     {"fqc",     "frame quality control", "set fqp min_i:max_i:min_p:max_p",         mpi_enc_opt_fqc},
758     {"s",       "instance_nb",          "number of instances",                      mpi_enc_opt_s},
759     {"v",       "trace option",         "q - quiet f - show fps",                   mpi_enc_opt_v},
760     {"l",       "loop count",           "loop encoding times for each frame",       mpi_enc_opt_l},
761     {"ini",     "ini file",             "encoder extra ini config file",            mpi_enc_opt_ini},
762     {"slt",     "slt file",             "slt verify data file",                     mpi_enc_opt_slt},
763     {"step",    "frame step",           "frame step, only for NV12 in slt test",    mpi_enc_opt_step},
764     {"sm",      "scene mode",           "scene_mode, 0:default 1:ipc",              mpi_enc_opt_sm},
765     {"qpdd",    "cu_qp_delta_depth",    "cu_qp_delta_depth, 0:1:2",                 mpi_enc_opt_qpdd},
766     {"dbe",     "deblur enable",        "deblur_en or qpmap_en, 0:close 1:open",           mpi_enc_opt_dbe},
767     {"dbs",     "deblur strength",      "deblur_str 0~3: hw + sw scheme; 4~7: hw scheme",  mpi_enc_opt_dbs},
768     {"atf",     "anti_flicker_str",     "anti_flicker_str, 0:off 1 2 3",            mpi_enc_opt_atf},
769     {"atl",     "atl_str",              "atl_str, 0:off 1 open",                    mpi_enc_opt_atl},
770     {"atr_i",   "atr_str_i",            "atr_str_i, 0:off 1 2 3",                   mpi_enc_opt_atr_i},
771     {"atr_p",   "atr_str_p",            "atr_str_p, 0:off 1 2 3",                   mpi_enc_opt_atr_p},
772     {"sao_i",   "sao_str_i",            "sao_str_i, 0:off 1 2 3",                   mpi_enc_opt_sao_i},
773     {"sao_p",   "sao_str_p",            "sao_str_p, 0:off 1 2 3",                   mpi_enc_opt_sao_p},
774     {"bc",      "bitrate container",    "rc_container, 0:off 1:weak 2:strong",      mpi_enc_opt_bc},
775     {"ibias",   "bias i",               "bias_i",                                   mpi_enc_opt_bias_i},
776     {"pbias",   "bias p",               "bias_p",                                   mpi_enc_opt_bias_p},
777     {"lmd",     "lambda idx",           "lambda_idx_p 0~8",                         mpi_enc_opt_lmd},
778     {"lmdi",    "lambda i idx",         "lambda_idx_i 0~8",                         mpi_enc_opt_lmdi},
779     {"speed",   "enc speed",            "speed mode",                               mpi_enc_opt_speed},
780     {"kmpp",    "kmpp path enable",     "kmpp path enable",                         mpi_enc_opt_kmpp}
781 };
782 
783 static RK_U32 enc_opt_cnt = MPP_ARRAY_ELEMS(enc_opts);
784 
mpi_enc_show_help(const char * name)785 RK_S32 mpi_enc_show_help(const char *name)
786 {
787     RK_U32 max_name = 1;
788     RK_U32 max_full_name = 1;
789     RK_U32 max_help = 1;
790     char logs[256];
791     RK_U32 len;
792     RK_U32 i;
793 
794     mpp_log("usage: %s [options]\n", name);
795 
796     for (i = 0; i < enc_opt_cnt; i++) {
797         MppOptInfo *opt = &enc_opts[i];
798 
799         if (opt->name) {
800             len = strlen(opt->name);
801             if (len > max_name)
802                 max_name = len;
803         }
804 
805         if (opt->full_name) {
806             len = strlen(opt->full_name);
807             if (len > max_full_name)
808                 max_full_name = len;
809         }
810 
811         if (opt->help) {
812             len = strlen(opt->help);
813             if (len > max_help)
814                 max_help = len;
815         }
816     }
817 
818     snprintf(logs, sizeof(logs) - 1, "-%%-%ds %%-%ds %%-%ds\n", max_name, max_full_name, max_help);
819 
820     for (i = 0; i < enc_opt_cnt; i++) {
821         MppOptInfo *opt = &enc_opts[i];
822 
823         mpp_log(logs, opt->name, opt->full_name, opt->help);
824     }
825     mpp_show_support_format();
826     mpp_show_color_format();
827 
828     return -1;
829 }
830 
show_enc_fps(RK_S64 total_time,RK_S64 total_count,RK_S64 last_time,RK_S64 last_count)831 void show_enc_fps(RK_S64 total_time, RK_S64 total_count, RK_S64 last_time, RK_S64 last_count)
832 {
833     float avg_fps = (float)total_count * 1000000 / total_time;
834     float ins_fps = (float)last_count * 1000000 / last_time;
835 
836     mpp_log("encoded %10lld frame fps avg %7.2f ins %7.2f\n",
837             total_count, avg_fps, ins_fps);
838 }
839 
mpi_enc_test_cmd_update_by_args(MpiEncTestArgs * cmd,int argc,char ** argv)840 MPP_RET mpi_enc_test_cmd_update_by_args(MpiEncTestArgs* cmd, int argc, char **argv)
841 {
842     MppOpt opts = NULL;
843     RK_S32 ret = -1;
844     RK_U32 i;
845 
846     if ((argc < 2) || NULL == cmd || NULL == argv)
847         goto done;
848 
849     cmd->rc_mode = MPP_ENC_RC_MODE_BUTT;
850 
851     mpp_opt_init(&opts);
852     mpp_opt_setup(opts, cmd);
853 
854     for (i = 0; i < enc_opt_cnt; i++)
855         mpp_opt_add(opts, &enc_opts[i]);
856 
857     /* mark option end */
858     mpp_opt_add(opts, NULL);
859     ret = mpp_opt_parse(opts, argc, argv);
860     /* check essential parameter */
861     if (cmd->type <= MPP_VIDEO_CodingAutoDetect) {
862         mpp_err("invalid type %d\n", cmd->type);
863         ret = MPP_NOK;
864     }
865 
866     if (cmd->rc_mode == MPP_ENC_RC_MODE_BUTT)
867         cmd->rc_mode = (cmd->type == MPP_VIDEO_CodingMJPEG) ?
868                        MPP_ENC_RC_MODE_FIXQP : MPP_ENC_RC_MODE_VBR;
869 
870     if (!cmd->hor_stride)
871         cmd->hor_stride = mpi_enc_width_default_stride(cmd->width, cmd->format);
872     if (!cmd->ver_stride)
873         cmd->ver_stride = MPP_ALIGN(cmd->height, 2);
874 
875     if (cmd->type_src == MPP_VIDEO_CodingUnused) {
876         if (cmd->width <= 0 || cmd->height <= 0 ||
877             cmd->hor_stride <= 0 || cmd->ver_stride <= 0) {
878             mpp_err("invalid w:h [%d:%d] stride [%d:%d]\n",
879                     cmd->width, cmd->height, cmd->hor_stride, cmd->ver_stride);
880             ret = MPP_NOK;
881         }
882     }
883 
884     if (cmd->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
885         if (!cmd->qp_init) {
886             if (cmd->type == MPP_VIDEO_CodingAVC ||
887                 cmd->type == MPP_VIDEO_CodingHEVC)
888                 cmd->qp_init = 26;
889         }
890     }
891 
892     if (cmd->trace_fps) {
893         fps_calc_init(&cmd->fps);
894         mpp_assert(cmd->fps);
895         fps_calc_set_cb(cmd->fps, show_enc_fps);
896     }
897 
898 done:
899     if (opts) {
900         mpp_opt_deinit(opts);
901         opts = NULL;
902     }
903     if (ret)
904         mpi_enc_show_help(argv[0]);
905 
906     return ret;
907 }
908 
mpi_enc_test_cmd_put(MpiEncTestArgs * cmd)909 MPP_RET mpi_enc_test_cmd_put(MpiEncTestArgs* cmd)
910 {
911     if (NULL == cmd)
912         return MPP_OK;
913 
914     if (cmd->cfg_ini) {
915         iniparser_freedict(cmd->cfg_ini);
916         cmd->cfg_ini = NULL;
917     }
918 
919     if (cmd->fps) {
920         fps_calc_deinit(cmd->fps);
921         cmd->fps = NULL;
922     }
923 
924     MPP_FREE(cmd->file_input);
925     MPP_FREE(cmd->file_output);
926     MPP_FREE(cmd->file_cfg);
927     MPP_FREE(cmd->file_slt);
928     MPP_FREE(cmd);
929 
930     return MPP_OK;
931 }
932 
mpi_enc_gen_ref_cfg(MppEncRefCfg ref,RK_S32 gop_mode)933 MPP_RET mpi_enc_gen_ref_cfg(MppEncRefCfg ref, RK_S32 gop_mode)
934 {
935     MppEncRefLtFrmCfg lt_ref[4];
936     MppEncRefStFrmCfg st_ref[16];
937     RK_S32 lt_cnt = 0;
938     RK_S32 st_cnt = 0;
939     MPP_RET ret = MPP_OK;
940 
941     memset(&lt_ref, 0, sizeof(lt_ref));
942     memset(&st_ref, 0, sizeof(st_ref));
943 
944     switch (gop_mode) {
945     case 3 : {
946         // tsvc4
947         //      /-> P1      /-> P3        /-> P5      /-> P7
948         //     /           /             /           /
949         //    //--------> P2            //--------> P6
950         //   //                        //
951         //  ///---------------------> P4
952         // ///
953         // P0 ------------------------------------------------> P8
954         lt_cnt = 1;
955 
956         /* set 8 frame lt-ref gap */
957         lt_ref[0].lt_idx        = 0;
958         lt_ref[0].temporal_id   = 0;
959         lt_ref[0].ref_mode      = REF_TO_PREV_LT_REF;
960         lt_ref[0].lt_gap        = 8;
961         lt_ref[0].lt_delay      = 0;
962 
963         st_cnt = 9;
964         /* set tsvc4 st-ref struct */
965         /* st 0 layer 0 - ref */
966         st_ref[0].is_non_ref    = 0;
967         st_ref[0].temporal_id   = 0;
968         st_ref[0].ref_mode      = REF_TO_TEMPORAL_LAYER;
969         st_ref[0].ref_arg       = 0;
970         st_ref[0].repeat        = 0;
971         /* st 1 layer 3 - non-ref */
972         st_ref[1].is_non_ref    = 1;
973         st_ref[1].temporal_id   = 3;
974         st_ref[1].ref_mode      = REF_TO_PREV_REF_FRM;
975         st_ref[1].ref_arg       = 0;
976         st_ref[1].repeat        = 0;
977         /* st 2 layer 2 - ref */
978         st_ref[2].is_non_ref    = 0;
979         st_ref[2].temporal_id   = 2;
980         st_ref[2].ref_mode      = REF_TO_PREV_REF_FRM;
981         st_ref[2].ref_arg       = 0;
982         st_ref[2].repeat        = 0;
983         /* st 3 layer 3 - non-ref */
984         st_ref[3].is_non_ref    = 1;
985         st_ref[3].temporal_id   = 3;
986         st_ref[3].ref_mode      = REF_TO_PREV_REF_FRM;
987         st_ref[3].ref_arg       = 0;
988         st_ref[3].repeat        = 0;
989         /* st 4 layer 1 - ref */
990         st_ref[4].is_non_ref    = 0;
991         st_ref[4].temporal_id   = 1;
992         st_ref[4].ref_mode      = REF_TO_PREV_LT_REF;
993         st_ref[4].ref_arg       = 0;
994         st_ref[4].repeat        = 0;
995         /* st 5 layer 3 - non-ref */
996         st_ref[5].is_non_ref    = 1;
997         st_ref[5].temporal_id   = 3;
998         st_ref[5].ref_mode      = REF_TO_PREV_REF_FRM;
999         st_ref[5].ref_arg       = 0;
1000         st_ref[5].repeat        = 0;
1001         /* st 6 layer 2 - ref */
1002         st_ref[6].is_non_ref    = 0;
1003         st_ref[6].temporal_id   = 2;
1004         st_ref[6].ref_mode      = REF_TO_PREV_REF_FRM;
1005         st_ref[6].ref_arg       = 0;
1006         st_ref[6].repeat        = 0;
1007         /* st 7 layer 3 - non-ref */
1008         st_ref[7].is_non_ref    = 1;
1009         st_ref[7].temporal_id   = 3;
1010         st_ref[7].ref_mode      = REF_TO_PREV_REF_FRM;
1011         st_ref[7].ref_arg       = 0;
1012         st_ref[7].repeat        = 0;
1013         /* st 8 layer 0 - ref */
1014         st_ref[8].is_non_ref    = 0;
1015         st_ref[8].temporal_id   = 0;
1016         st_ref[8].ref_mode      = REF_TO_TEMPORAL_LAYER;
1017         st_ref[8].ref_arg       = 0;
1018         st_ref[8].repeat        = 0;
1019     } break;
1020     case 2 : {
1021         // tsvc3
1022         //     /-> P1      /-> P3
1023         //    /           /
1024         //   //--------> P2
1025         //  //
1026         // P0/---------------------> P4
1027         lt_cnt = 0;
1028 
1029         st_cnt = 5;
1030         /* set tsvc4 st-ref struct */
1031         /* st 0 layer 0 - ref */
1032         st_ref[0].is_non_ref    = 0;
1033         st_ref[0].temporal_id   = 0;
1034         st_ref[0].ref_mode      = REF_TO_TEMPORAL_LAYER;
1035         st_ref[0].ref_arg       = 0;
1036         st_ref[0].repeat        = 0;
1037         /* st 1 layer 2 - non-ref */
1038         st_ref[1].is_non_ref    = 1;
1039         st_ref[1].temporal_id   = 2;
1040         st_ref[1].ref_mode      = REF_TO_PREV_REF_FRM;
1041         st_ref[1].ref_arg       = 0;
1042         st_ref[1].repeat        = 0;
1043         /* st 2 layer 1 - ref */
1044         st_ref[2].is_non_ref    = 0;
1045         st_ref[2].temporal_id   = 1;
1046         st_ref[2].ref_mode      = REF_TO_PREV_REF_FRM;
1047         st_ref[2].ref_arg       = 0;
1048         st_ref[2].repeat        = 0;
1049         /* st 3 layer 2 - non-ref */
1050         st_ref[3].is_non_ref    = 1;
1051         st_ref[3].temporal_id   = 2;
1052         st_ref[3].ref_mode      = REF_TO_PREV_REF_FRM;
1053         st_ref[3].ref_arg       = 0;
1054         st_ref[3].repeat        = 0;
1055         /* st 4 layer 0 - ref */
1056         st_ref[4].is_non_ref    = 0;
1057         st_ref[4].temporal_id   = 0;
1058         st_ref[4].ref_mode      = REF_TO_TEMPORAL_LAYER;
1059         st_ref[4].ref_arg       = 0;
1060         st_ref[4].repeat        = 0;
1061     } break;
1062     case 1 : {
1063         // tsvc2
1064         //   /-> P1
1065         //  /
1066         // P0--------> P2
1067         lt_cnt = 0;
1068 
1069         st_cnt = 3;
1070         /* set tsvc4 st-ref struct */
1071         /* st 0 layer 0 - ref */
1072         st_ref[0].is_non_ref    = 0;
1073         st_ref[0].temporal_id   = 0;
1074         st_ref[0].ref_mode      = REF_TO_TEMPORAL_LAYER;
1075         st_ref[0].ref_arg       = 0;
1076         st_ref[0].repeat        = 0;
1077         /* st 1 layer 2 - non-ref */
1078         st_ref[1].is_non_ref    = 1;
1079         st_ref[1].temporal_id   = 1;
1080         st_ref[1].ref_mode      = REF_TO_PREV_REF_FRM;
1081         st_ref[1].ref_arg       = 0;
1082         st_ref[1].repeat        = 0;
1083         /* st 2 layer 1 - ref */
1084         st_ref[2].is_non_ref    = 0;
1085         st_ref[2].temporal_id   = 0;
1086         st_ref[2].ref_mode      = REF_TO_PREV_REF_FRM;
1087         st_ref[2].ref_arg       = 0;
1088         st_ref[2].repeat        = 0;
1089     } break;
1090     default : {
1091         mpp_err_f("unsupport gop mode %d\n", gop_mode);
1092     } break;
1093     }
1094 
1095     if (lt_cnt || st_cnt) {
1096         ret = mpp_enc_ref_cfg_set_cfg_cnt(ref, lt_cnt, st_cnt);
1097 
1098         if (lt_cnt)
1099             ret = mpp_enc_ref_cfg_add_lt_cfg(ref, lt_cnt, lt_ref);
1100 
1101         if (st_cnt)
1102             ret = mpp_enc_ref_cfg_add_st_cfg(ref, st_cnt, st_ref);
1103 
1104         /* check and get dpb size */
1105         ret = mpp_enc_ref_cfg_check(ref);
1106     }
1107 
1108     return ret;
1109 }
1110 
mpi_enc_gen_smart_gop_ref_cfg(MppEncRefCfg ref,RK_S32 gop_len,RK_S32 vi_len)1111 MPP_RET mpi_enc_gen_smart_gop_ref_cfg(MppEncRefCfg ref, RK_S32 gop_len, RK_S32 vi_len)
1112 {
1113     MppEncRefLtFrmCfg lt_ref[4];
1114     MppEncRefStFrmCfg st_ref[16];
1115     RK_S32 lt_cnt = 1;
1116     RK_S32 st_cnt = 8;
1117     RK_S32 pos = 0;
1118     MPP_RET ret = MPP_OK;
1119 
1120     memset(&lt_ref, 0, sizeof(lt_ref));
1121     memset(&st_ref, 0, sizeof(st_ref));
1122 
1123     ret = mpp_enc_ref_cfg_set_cfg_cnt(ref, lt_cnt, st_cnt);
1124 
1125     /* set 8 frame lt-ref gap */
1126     lt_ref[0].lt_idx        = 0;
1127     lt_ref[0].temporal_id   = 0;
1128     lt_ref[0].ref_mode      = REF_TO_PREV_LT_REF;
1129     lt_ref[0].lt_gap        = gop_len;
1130     lt_ref[0].lt_delay      = 0;
1131 
1132     ret = mpp_enc_ref_cfg_add_lt_cfg(ref, 1, lt_ref);
1133 
1134     /* st 0 layer 0 - ref */
1135     st_ref[pos].is_non_ref  = 0;
1136     st_ref[pos].temporal_id = 0;
1137     st_ref[pos].ref_mode    = REF_TO_PREV_INTRA;
1138     st_ref[pos].ref_arg     = 0;
1139     st_ref[pos].repeat      = 0;
1140     pos++;
1141 
1142     /* st 1 layer 1 - non-ref */
1143     if (vi_len > 1) {
1144         st_ref[pos].is_non_ref  = 0;
1145         st_ref[pos].temporal_id = 0;
1146         st_ref[pos].ref_mode    = REF_TO_PREV_REF_FRM;
1147         st_ref[pos].ref_arg     = 0;
1148         st_ref[pos].repeat      = vi_len - 2;
1149         pos++;
1150     }
1151 
1152     st_ref[pos].is_non_ref  = 0;
1153     st_ref[pos].temporal_id = 0;
1154     st_ref[pos].ref_mode    = REF_TO_PREV_INTRA;
1155     st_ref[pos].ref_arg     = 0;
1156     st_ref[pos].repeat      = 0;
1157     pos++;
1158 
1159     ret = mpp_enc_ref_cfg_add_st_cfg(ref, pos, st_ref);
1160 
1161     /* check and get dpb size */
1162     ret = mpp_enc_ref_cfg_check(ref);
1163 
1164     return ret;
1165 }
1166 
mpi_enc_gen_osd_plt(MppEncOSDPlt * osd_plt,RK_U32 frame_cnt)1167 MPP_RET mpi_enc_gen_osd_plt(MppEncOSDPlt *osd_plt, RK_U32 frame_cnt)
1168 {
1169     /*
1170      * osd idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes).
1171      * for general use, 1/8 Y buffer is enough.
1172      */
1173     static RK_U32 plt_table[8] = {
1174         MPP_ENC_OSD_PLT_RED,
1175         MPP_ENC_OSD_PLT_YELLOW,
1176         MPP_ENC_OSD_PLT_BLUE,
1177         MPP_ENC_OSD_PLT_GREEN,
1178         MPP_ENC_OSD_PLT_CYAN,
1179         MPP_ENC_OSD_PLT_TRANS,
1180         MPP_ENC_OSD_PLT_BLACK,
1181         MPP_ENC_OSD_PLT_WHITE,
1182     };
1183 
1184     if (osd_plt) {
1185         RK_U32 k = 0;
1186         RK_U32 base = frame_cnt & 7;
1187 
1188         for (k = 0; k < 256; k++)
1189             osd_plt->data[k].val = plt_table[(base + k) % 8];
1190     }
1191     return MPP_OK;
1192 }
1193 
mpi_enc_gen_osd_data(MppEncOSDData * osd_data,MppBufferGroup group,RK_U32 width,RK_U32 height,RK_U32 frame_cnt)1194 MPP_RET mpi_enc_gen_osd_data(MppEncOSDData *osd_data, MppBufferGroup group,
1195                              RK_U32 width, RK_U32 height, RK_U32 frame_cnt)
1196 {
1197     MppEncOSDRegion *region = NULL;
1198     RK_U32 k = 0;
1199     RK_U32 num_region = 8;
1200     RK_U32 buf_offset = 0;
1201     RK_U32 buf_size = 0;
1202     RK_U32 mb_w_max = MPP_ALIGN(width, 16) / 16;
1203     RK_U32 mb_h_max = MPP_ALIGN(height, 16) / 16;
1204     RK_U32 step_x = MPP_ALIGN(mb_w_max, 8) / 8;
1205     RK_U32 step_y = MPP_ALIGN(mb_h_max, 16) / 16;
1206     RK_U32 mb_x = (frame_cnt * step_x) % mb_w_max;
1207     RK_U32 mb_y = (frame_cnt * step_y) % mb_h_max;
1208     RK_U32 mb_w = step_x;
1209     RK_U32 mb_h = step_y;
1210     MppBuffer buf = osd_data->buf;
1211 
1212     if (buf)
1213         buf_size = mpp_buffer_get_size(buf);
1214 
1215     /* generate osd region info */
1216     osd_data->num_region = num_region;
1217 
1218     region = osd_data->region;
1219 
1220     for (k = 0; k < num_region; k++, region++) {
1221         // NOTE: offset must be 16 byte aligned
1222         RK_U32 region_size = MPP_ALIGN(mb_w * mb_h * 256, 16);
1223 
1224         region->inverse = 1;
1225         region->start_mb_x = mb_x;
1226         region->start_mb_y = mb_y;
1227         region->num_mb_x = mb_w;
1228         region->num_mb_y = mb_h;
1229         region->buf_offset = buf_offset;
1230         region->enable = (mb_w && mb_h);
1231 
1232         buf_offset += region_size;
1233 
1234         mb_x += step_x;
1235         mb_y += step_y;
1236         if (mb_x >= mb_w_max)
1237             mb_x -= mb_w_max;
1238         if (mb_y >= mb_h_max)
1239             mb_y -= mb_h_max;
1240     }
1241 
1242     /* create buffer and write osd index data */
1243     if (buf_size < buf_offset) {
1244         if (buf)
1245             mpp_buffer_put(buf);
1246 
1247         mpp_buffer_get(group, &buf, buf_offset);
1248         if (NULL == buf)
1249             mpp_err_f("failed to create osd buffer size %d\n", buf_offset);
1250     }
1251 
1252     if (buf) {
1253         void *ptr = mpp_buffer_get_ptr(buf);
1254         region = osd_data->region;
1255 
1256         for (k = 0; k < num_region; k++, region++) {
1257             mb_w = region->num_mb_x;
1258             mb_h = region->num_mb_y;
1259             buf_offset = region->buf_offset;
1260 
1261             memset(ptr + buf_offset, k, mb_w * mb_h * 256);
1262         }
1263     }
1264 
1265     osd_data->buf = buf;
1266 
1267     return MPP_OK;
1268 }
1269 
mpi_enc_test_cmd_show_opt(MpiEncTestArgs * cmd)1270 MPP_RET mpi_enc_test_cmd_show_opt(MpiEncTestArgs* cmd)
1271 {
1272     mpp_log("cmd parse result:\n");
1273     mpp_log("input  file name: %s\n", cmd->file_input);
1274     mpp_log("output file name: %s\n", cmd->file_output);
1275     mpp_log("width      : %d\n", cmd->width);
1276     mpp_log("height     : %d\n", cmd->height);
1277     mpp_log("format     : %d\n", cmd->format);
1278     mpp_log("type       : %d\n", cmd->type);
1279     if (cmd->file_slt) {
1280         mpp_log("verify     : %s\n", cmd->file_slt);
1281         mpp_log("frame step : %d\n", cmd->frm_step);
1282     }
1283 
1284     return MPP_OK;
1285 }
1286