mpi_enc_test.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  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. #if defined(_WIN32)
  17. #include "vld.h"
  18. #endif
  19. #define MODULE_TAG "mpi_enc_test"
  20. #include <string.h>
  21. #include <math.h>
  22. #include "rk_mpi.h"
  23. #include "rk_venc_kcfg.h"
  24. #include "mpp_env.h"
  25. #include "mpp_mem.h"
  26. #include "mpp_time.h"
  27. #include "mpp_debug.h"
  28. #include "mpp_common.h"
  29. #include "mpp_soc.h"
  30. #include "utils.h"
  31. #include "mpi_enc_utils.h"
  32. #include "camera_source.h"
  33. #include "mpp_enc_roi_utils.h"
  34. #include "mpp_rc_api.h"
  35. static RK_S32 aq_thd_smart[16] = {
  36. 1, 3, 3, 3, 3, 3, 5, 5,
  37. 8, 8, 8, 15, 15, 20, 25, 28
  38. };
  39. static RK_S32 aq_step_smart[16] = {
  40. -8, -7, -6, -5, -4, -3, -2, -1,
  41. 0, 1, 2, 3, 4, 6, 8, 10
  42. };
  43. typedef struct {
  44. // base flow context
  45. MppCtx ctx;
  46. MppApi *mpi;
  47. RK_S32 chn;
  48. // global flow control flag
  49. RK_U32 frm_eos;
  50. RK_U32 pkt_eos;
  51. RK_U32 frm_pkt_cnt;
  52. RK_S32 frame_num;
  53. RK_S32 frame_count;
  54. RK_U64 stream_size;
  55. /* end of encoding flag when set quit the loop */
  56. volatile RK_U32 loop_end;
  57. // src and dst
  58. FILE *fp_input;
  59. FILE *fp_output;
  60. FILE *fp_verify;
  61. /* encoder config set */
  62. MppEncCfg cfg;
  63. MppEncPrepCfg prep_cfg;
  64. MppEncRcCfg rc_cfg;
  65. MppEncCodecCfg codec_cfg;
  66. MppEncSliceSplit split_cfg;
  67. MppEncOSDPltCfg osd_plt_cfg;
  68. MppEncOSDPlt osd_plt;
  69. MppEncOSDData osd_data;
  70. RoiRegionCfg roi_region;
  71. MppEncROICfg roi_cfg;
  72. // input / output
  73. MppBufferGroup buf_grp;
  74. MppBuffer frm_buf;
  75. MppBuffer pkt_buf;
  76. MppBuffer md_info;
  77. MppEncSeiMode sei_mode;
  78. MppEncHeaderMode header_mode;
  79. // paramter for resource malloc
  80. RK_U32 width;
  81. RK_U32 height;
  82. RK_U32 hor_stride;
  83. RK_U32 ver_stride;
  84. MppFrameFormat fmt;
  85. MppCodingType type;
  86. RK_S32 loop_times;
  87. CamSource *cam_ctx;
  88. MppEncRoiCtx roi_ctx;
  89. KmppVenccfg init_kcfg;
  90. // resources
  91. size_t header_size;
  92. size_t frame_size;
  93. size_t mdinfo_size;
  94. /* NOTE: packet buffer may overflow */
  95. size_t packet_size;
  96. RK_U32 osd_enable;
  97. RK_U32 osd_mode;
  98. RK_U32 split_mode;
  99. RK_U32 split_arg;
  100. RK_U32 split_out;
  101. RK_U32 user_data_enable;
  102. RK_U32 roi_enable;
  103. // rate control runtime parameter
  104. RK_S32 fps_in_flex;
  105. RK_S32 fps_in_den;
  106. RK_S32 fps_in_num;
  107. RK_S32 fps_out_flex;
  108. RK_S32 fps_out_den;
  109. RK_S32 fps_out_num;
  110. RK_S32 bps;
  111. RK_S32 bps_max;
  112. RK_S32 bps_min;
  113. RK_S32 rc_mode;
  114. RK_S32 gop_mode;
  115. RK_S32 gop_len;
  116. RK_S32 vi_len;
  117. RK_S32 scene_mode;
  118. RK_S32 cu_qp_delta_depth;
  119. RK_S32 anti_flicker_str;
  120. RK_S32 atr_str_i;
  121. RK_S32 atr_str_p;
  122. RK_S32 atl_str;
  123. RK_S32 sao_str_i;
  124. RK_S32 sao_str_p;
  125. RK_S64 first_frm;
  126. RK_S64 first_pkt;
  127. } MpiEncTestData;
  128. /* For each instance thread return value */
  129. typedef struct {
  130. float frame_rate;
  131. RK_U64 bit_rate;
  132. RK_S64 elapsed_time;
  133. RK_S32 frame_count;
  134. RK_S64 stream_size;
  135. RK_S64 delay;
  136. } MpiEncMultiCtxRet;
  137. typedef struct {
  138. MpiEncTestArgs *cmd; // pointer to global command line info
  139. const char *name;
  140. RK_S32 chn;
  141. pthread_t thd; // thread for for each instance
  142. MpiEncTestData ctx; // context of encoder
  143. MpiEncMultiCtxRet ret; // return of encoder
  144. } MpiEncMultiCtxInfo;
  145. static RK_S32 aq_thd[16] = {
  146. 0, 0, 0, 0,
  147. 3, 3, 5, 5,
  148. 8, 8, 8, 15,
  149. 15, 20, 25, 25
  150. };
  151. static RK_S32 aq_step_i_ipc[16] = {
  152. -8, -7, -6, -5,
  153. -4, -3, -2, -1,
  154. 0, 1, 2, 3,
  155. 5, 7, 7, 8,
  156. };
  157. static RK_S32 aq_step_p_ipc[16] = {
  158. -8, -7, -6, -5,
  159. -4, -2, -1, -1,
  160. 0, 2, 3, 4,
  161. 6, 8, 9, 10,
  162. };
  163. static RK_S32 get_mdinfo_size(MpiEncTestData *p, MppCodingType type)
  164. {
  165. RockchipSocType soc_type = mpp_get_soc_type();
  166. RK_S32 md_size;
  167. RK_U32 w = p->hor_stride, h = p->ver_stride;
  168. if (soc_type == ROCKCHIP_SOC_RK3588) {
  169. md_size = (MPP_ALIGN(w, 64) >> 6) * (MPP_ALIGN(h, 64) >> 6) * 32;
  170. } else {
  171. md_size = (MPP_VIDEO_CodingHEVC == type) ?
  172. (MPP_ALIGN(w, 32) >> 5) * (MPP_ALIGN(h, 32) >> 5) * 16 :
  173. (MPP_ALIGN(w, 64) >> 6) * (MPP_ALIGN(h, 16) >> 4) * 16;
  174. }
  175. return md_size;
  176. }
  177. static MPP_RET kmpp_cfg_init(MpiEncMultiCtxInfo *info)
  178. {
  179. KmppVenccfg init_kcfg = NULL;
  180. MpiEncTestData *p = &info->ctx;
  181. MPP_RET ret = MPP_NOK;
  182. kmpp_venc_cfg_init(&init_kcfg, KMPP_VENC_CFG_TYPE_INIT);
  183. if (!init_kcfg) {
  184. mpp_err_f("kmpp_venc_init_cfg_init failed\n");
  185. return ret;
  186. }
  187. p->init_kcfg = init_kcfg;
  188. kmpp_venc_cfg_set_u32(init_kcfg, "type", MPP_CTX_ENC);
  189. kmpp_venc_cfg_set_u32(init_kcfg, "coding", p->type);
  190. kmpp_venc_cfg_set_s32(init_kcfg, "chan_id", 0);
  191. kmpp_venc_cfg_set_s32(init_kcfg, "online", 0);
  192. kmpp_venc_cfg_set_u32(init_kcfg, "buf_size", 0);
  193. kmpp_venc_cfg_set_u32(init_kcfg, "max_strm_cnt", 0);
  194. kmpp_venc_cfg_set_u32(init_kcfg, "shared_buf_en", 0);
  195. kmpp_venc_cfg_set_u32(init_kcfg, "smart_en", 0);
  196. kmpp_venc_cfg_set_u32(init_kcfg, "max_width", p->width);
  197. kmpp_venc_cfg_set_u32(init_kcfg, "max_height", p->height);
  198. kmpp_venc_cfg_set_u32(init_kcfg, "max_lt_cnt", 0);
  199. kmpp_venc_cfg_set_u32(init_kcfg, "qpmap_en", 0);
  200. kmpp_venc_cfg_set_u32(init_kcfg, "chan_dup", 0);
  201. kmpp_venc_cfg_set_u32(init_kcfg, "tmvp_enable", 0);
  202. kmpp_venc_cfg_set_u32(init_kcfg, "only_smartp", 0);
  203. ret = p->mpi->control(p->ctx, MPP_SET_VENC_INIT_KCFG, init_kcfg);
  204. if (ret)
  205. mpp_err_f("mpi control set kmpp enc cfg failed ret %d\n", ret);
  206. return ret;
  207. }
  208. MPP_RET test_ctx_init(MpiEncMultiCtxInfo *info)
  209. {
  210. MpiEncTestArgs *cmd = info->cmd;
  211. MpiEncTestData *p = &info->ctx;
  212. MPP_RET ret = MPP_OK;
  213. // get paramter from cmd
  214. p->width = cmd->width;
  215. p->height = cmd->height;
  216. p->hor_stride = (cmd->hor_stride) ? (cmd->hor_stride) :
  217. (MPP_ALIGN(cmd->width, 16));
  218. p->ver_stride = (cmd->ver_stride) ? (cmd->ver_stride) :
  219. (MPP_ALIGN(cmd->height, 16));
  220. p->fmt = cmd->format;
  221. p->type = cmd->type;
  222. p->bps = cmd->bps_target;
  223. p->bps_min = cmd->bps_min;
  224. p->bps_max = cmd->bps_max;
  225. p->rc_mode = cmd->rc_mode;
  226. p->frame_num = cmd->frame_num;
  227. if (cmd->type == MPP_VIDEO_CodingMJPEG && p->frame_num == 0) {
  228. mpp_log("jpege default encode only one frame. Use -n [num] for rc case\n");
  229. p->frame_num = 1;
  230. }
  231. p->gop_mode = cmd->gop_mode;
  232. p->gop_len = cmd->gop_len;
  233. p->vi_len = cmd->vi_len;
  234. p->fps_in_flex = cmd->fps_in_flex;
  235. p->fps_in_den = cmd->fps_in_den;
  236. p->fps_in_num = cmd->fps_in_num;
  237. p->fps_out_flex = cmd->fps_out_flex;
  238. p->fps_out_den = cmd->fps_out_den;
  239. p->fps_out_num = cmd->fps_out_num;
  240. p->scene_mode = cmd->scene_mode;
  241. p->cu_qp_delta_depth = cmd->cu_qp_delta_depth;
  242. p->anti_flicker_str = cmd->anti_flicker_str;
  243. p->atr_str_i = cmd->atr_str_i;
  244. p->atr_str_p = cmd->atr_str_p;
  245. p->atl_str = cmd->atl_str;
  246. p->sao_str_i = cmd->sao_str_i;
  247. p->sao_str_p = cmd->sao_str_p;
  248. p->mdinfo_size = get_mdinfo_size(p, cmd->type);
  249. if (cmd->file_input) {
  250. if (!strncmp(cmd->file_input, "/dev/video", 10)) {
  251. mpp_log("open camera device");
  252. p->cam_ctx = camera_source_init(cmd->file_input, 4, p->width, p->height, p->fmt);
  253. mpp_log("new framecap ok");
  254. if (p->cam_ctx == NULL)
  255. mpp_err("open %s fail", cmd->file_input);
  256. } else {
  257. p->fp_input = fopen(cmd->file_input, "rb");
  258. if (NULL == p->fp_input) {
  259. mpp_err("failed to open input file %s\n", cmd->file_input);
  260. mpp_err("create default yuv image for test\n");
  261. }
  262. }
  263. }
  264. if (cmd->file_output) {
  265. p->fp_output = fopen(cmd->file_output, "w+b");
  266. if (NULL == p->fp_output) {
  267. mpp_err("failed to open output file %s\n", cmd->file_output);
  268. ret = MPP_ERR_OPEN_FILE;
  269. }
  270. }
  271. if (cmd->file_slt) {
  272. p->fp_verify = fopen(cmd->file_slt, "wt");
  273. if (!p->fp_verify)
  274. mpp_err("failed to open verify file %s\n", cmd->file_slt);
  275. }
  276. // update resource parameter
  277. switch (p->fmt & MPP_FRAME_FMT_MASK) {
  278. case MPP_FMT_YUV420SP:
  279. case MPP_FMT_YUV420P: {
  280. p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 3 / 2;
  281. } break;
  282. case MPP_FMT_YUV422_YUYV :
  283. case MPP_FMT_YUV422_YVYU :
  284. case MPP_FMT_YUV422_UYVY :
  285. case MPP_FMT_YUV422_VYUY :
  286. case MPP_FMT_YUV422P :
  287. case MPP_FMT_YUV422SP : {
  288. p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 2;
  289. } break;
  290. case MPP_FMT_YUV400:
  291. case MPP_FMT_RGB444 :
  292. case MPP_FMT_BGR444 :
  293. case MPP_FMT_RGB555 :
  294. case MPP_FMT_BGR555 :
  295. case MPP_FMT_RGB565 :
  296. case MPP_FMT_BGR565 :
  297. case MPP_FMT_RGB888 :
  298. case MPP_FMT_BGR888 :
  299. case MPP_FMT_RGB101010 :
  300. case MPP_FMT_BGR101010 :
  301. case MPP_FMT_ARGB8888 :
  302. case MPP_FMT_ABGR8888 :
  303. case MPP_FMT_BGRA8888 :
  304. case MPP_FMT_RGBA8888 : {
  305. p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64);
  306. } break;
  307. default: {
  308. p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 4;
  309. } break;
  310. }
  311. if (MPP_FRAME_FMT_IS_FBC(p->fmt)) {
  312. if ((p->fmt & MPP_FRAME_FBC_MASK) == MPP_FRAME_FBC_AFBC_V1)
  313. p->header_size = MPP_ALIGN(MPP_ALIGN(p->width, 16) * MPP_ALIGN(p->height, 16) / 16, SZ_4K);
  314. else
  315. p->header_size = MPP_ALIGN(p->width, 16) * MPP_ALIGN(p->height, 16) / 16;
  316. } else {
  317. p->header_size = 0;
  318. }
  319. return ret;
  320. }
  321. MPP_RET test_ctx_deinit(MpiEncTestData *p)
  322. {
  323. if (p) {
  324. if (p->cam_ctx) {
  325. camera_source_deinit(p->cam_ctx);
  326. p->cam_ctx = NULL;
  327. }
  328. if (p->fp_input) {
  329. fclose(p->fp_input);
  330. p->fp_input = NULL;
  331. }
  332. if (p->fp_output) {
  333. fclose(p->fp_output);
  334. p->fp_output = NULL;
  335. }
  336. if (p->fp_verify) {
  337. fclose(p->fp_verify);
  338. p->fp_verify = NULL;
  339. }
  340. }
  341. return MPP_OK;
  342. }
  343. MPP_RET test_mpp_enc_cfg_setup(MpiEncMultiCtxInfo *info)
  344. {
  345. MpiEncTestArgs *cmd = info->cmd;
  346. MpiEncTestData *p = &info->ctx;
  347. MppApi *mpi = p->mpi;
  348. MppCtx ctx = p->ctx;
  349. MppEncCfg cfg = p->cfg;
  350. RK_U32 quiet = cmd->quiet;
  351. MPP_RET ret;
  352. RK_U32 rotation;
  353. RK_U32 mirroring;
  354. RK_U32 flip;
  355. RK_U32 gop_mode = p->gop_mode;
  356. MppEncRefCfg ref = NULL;
  357. /* setup default parameter */
  358. if (p->fps_in_den == 0)
  359. p->fps_in_den = 1;
  360. if (p->fps_in_num == 0)
  361. p->fps_in_num = 30;
  362. if (p->fps_out_den == 0)
  363. p->fps_out_den = 1;
  364. if (p->fps_out_num == 0)
  365. p->fps_out_num = 30;
  366. if (!p->bps)
  367. p->bps = p->width * p->height / 8 * (p->fps_out_num / p->fps_out_den);
  368. if (cmd->rc_mode == MPP_ENC_RC_MODE_SMTRC) {
  369. mpp_enc_cfg_set_st(cfg, "hw:aq_thrd_i", aq_thd_smart);
  370. mpp_enc_cfg_set_st(cfg, "hw:aq_thrd_p", aq_thd_smart);
  371. mpp_enc_cfg_set_st(cfg, "hw:aq_step_i", aq_step_smart);
  372. mpp_enc_cfg_set_st(cfg, "hw:aq_step_p", aq_step_smart);
  373. } else {
  374. mpp_enc_cfg_set_st(cfg, "hw:aq_thrd_i", aq_thd);
  375. mpp_enc_cfg_set_st(cfg, "hw:aq_thrd_p", aq_thd);
  376. mpp_enc_cfg_set_st(cfg, "hw:aq_step_i", aq_step_i_ipc);
  377. mpp_enc_cfg_set_st(cfg, "hw:aq_step_p", aq_step_p_ipc);
  378. }
  379. mpp_enc_cfg_set_s32(cfg, "rc:max_reenc_times", 0);
  380. mpp_enc_cfg_set_s32(cfg, "tune:anti_flicker_str", p->anti_flicker_str);
  381. mpp_enc_cfg_set_s32(cfg, "tune:atr_str_i", p->atr_str_i);
  382. mpp_enc_cfg_set_s32(cfg, "tune:atr_str_p", p->atr_str_p);
  383. mpp_enc_cfg_set_s32(cfg, "tune:atl_str", p->atl_str);
  384. mpp_enc_cfg_set_s32(cfg, "tune:sao_str_i", p->sao_str_i);
  385. mpp_enc_cfg_set_s32(cfg, "tune:sao_str_p", p->sao_str_p);
  386. mpp_enc_cfg_set_s32(cfg, "tune:scene_mode", p->scene_mode);
  387. mpp_enc_cfg_set_s32(cfg, "tune:deblur_en", cmd->deblur_en);
  388. mpp_enc_cfg_set_s32(cfg, "tune:deblur_str", cmd->deblur_str);
  389. mpp_enc_cfg_set_s32(cfg, "tune:rc_container", cmd->rc_container);
  390. mpp_enc_cfg_set_s32(cfg, "tune:vmaf_opt", 0);
  391. mpp_enc_cfg_set_s32(cfg, "hw:qbias_en", 1);
  392. mpp_enc_cfg_set_s32(cfg, "hw:qbias_i", cmd->bias_i);
  393. mpp_enc_cfg_set_s32(cfg, "hw:qbias_p", cmd->bias_p);
  394. mpp_enc_cfg_set_s32(cfg, "hw:skip_bias_en", 0);
  395. mpp_enc_cfg_set_s32(cfg, "hw:skip_bias", 4);
  396. mpp_enc_cfg_set_s32(cfg, "hw:skip_sad", 8);
  397. mpp_enc_cfg_set_s32(cfg, "prep:width", p->width);
  398. mpp_enc_cfg_set_s32(cfg, "prep:height", p->height);
  399. mpp_enc_cfg_set_s32(cfg, "prep:hor_stride", p->hor_stride);
  400. mpp_enc_cfg_set_s32(cfg, "prep:ver_stride", p->ver_stride);
  401. mpp_enc_cfg_set_s32(cfg, "prep:format", p->fmt);
  402. mpp_enc_cfg_set_s32(cfg, "prep:range", MPP_FRAME_RANGE_JPEG);
  403. mpp_enc_cfg_set_s32(cfg, "rc:mode", p->rc_mode);
  404. mpp_enc_cfg_set_u32(cfg, "rc:max_reenc_times", 0);
  405. mpp_enc_cfg_set_u32(cfg, "rc:super_mode", 0);
  406. /* fix input / output frame rate */
  407. mpp_enc_cfg_set_s32(cfg, "rc:fps_in_flex", p->fps_in_flex);
  408. mpp_enc_cfg_set_s32(cfg, "rc:fps_in_num", p->fps_in_num);
  409. mpp_enc_cfg_set_s32(cfg, "rc:fps_in_denom", p->fps_in_den);
  410. mpp_enc_cfg_set_s32(cfg, "rc:fps_out_flex", p->fps_out_flex);
  411. mpp_enc_cfg_set_s32(cfg, "rc:fps_out_num", p->fps_out_num);
  412. mpp_enc_cfg_set_s32(cfg, "rc:fps_out_denom", p->fps_out_den);
  413. /* drop frame or not when bitrate overflow */
  414. mpp_enc_cfg_set_u32(cfg, "rc:drop_mode", MPP_ENC_RC_DROP_FRM_DISABLED);
  415. mpp_enc_cfg_set_u32(cfg, "rc:drop_thd", 20); /* 20% of max bps */
  416. mpp_enc_cfg_set_u32(cfg, "rc:drop_gap", 1); /* Do not continuous drop frame */
  417. /* setup bitrate for different rc_mode */
  418. mpp_enc_cfg_set_s32(cfg, "rc:bps_target", p->bps);
  419. switch (p->rc_mode) {
  420. case MPP_ENC_RC_MODE_FIXQP : {
  421. /* do not setup bitrate on FIXQP mode */
  422. } break;
  423. case MPP_ENC_RC_MODE_CBR : {
  424. /* CBR mode has narrow bound */
  425. mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
  426. mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
  427. } break;
  428. case MPP_ENC_RC_MODE_VBR :
  429. case MPP_ENC_RC_MODE_AVBR : {
  430. /* VBR mode has wide bound */
  431. mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
  432. mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 1 / 16);
  433. } break;
  434. default : {
  435. /* default use CBR mode */
  436. mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
  437. mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
  438. } break;
  439. }
  440. /* setup qp for different codec and rc_mode */
  441. switch (p->type) {
  442. case MPP_VIDEO_CodingAVC :
  443. case MPP_VIDEO_CodingHEVC : {
  444. switch (p->rc_mode) {
  445. case MPP_ENC_RC_MODE_FIXQP : {
  446. RK_S32 fix_qp = cmd->qp_init;
  447. mpp_enc_cfg_set_s32(cfg, "rc:qp_init", fix_qp);
  448. mpp_enc_cfg_set_s32(cfg, "rc:qp_max", fix_qp);
  449. mpp_enc_cfg_set_s32(cfg, "rc:qp_min", fix_qp);
  450. mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", fix_qp);
  451. mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", fix_qp);
  452. mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 0);
  453. mpp_enc_cfg_set_s32(cfg, "rc:fqp_min_i", fix_qp);
  454. mpp_enc_cfg_set_s32(cfg, "rc:fqp_max_i", fix_qp);
  455. mpp_enc_cfg_set_s32(cfg, "rc:fqp_min_p", fix_qp);
  456. mpp_enc_cfg_set_s32(cfg, "rc:fqp_max_p", fix_qp);
  457. } break;
  458. case MPP_ENC_RC_MODE_CBR :
  459. case MPP_ENC_RC_MODE_VBR :
  460. case MPP_ENC_RC_MODE_AVBR :
  461. case MPP_ENC_RC_MODE_SMTRC : {
  462. mpp_enc_cfg_set_s32(cfg, "rc:qp_init", cmd->qp_init ? cmd->qp_init : -1);
  463. mpp_enc_cfg_set_s32(cfg, "rc:qp_max", cmd->qp_max ? cmd->qp_max : 51);
  464. mpp_enc_cfg_set_s32(cfg, "rc:qp_min", cmd->qp_min ? cmd->qp_min : 10);
  465. mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", cmd->qp_max_i ? cmd->qp_max_i : 51);
  466. mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", cmd->qp_min_i ? cmd->qp_min_i : 10);
  467. mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 2);
  468. mpp_enc_cfg_set_s32(cfg, "rc:fqp_min_i", cmd->fqp_min_i ? cmd->fqp_min_i : 10);
  469. mpp_enc_cfg_set_s32(cfg, "rc:fqp_max_i", cmd->fqp_max_i ? cmd->fqp_max_i : 45);
  470. mpp_enc_cfg_set_s32(cfg, "rc:fqp_min_p", cmd->fqp_min_p ? cmd->fqp_min_p : 10);
  471. mpp_enc_cfg_set_s32(cfg, "rc:fqp_max_p", cmd->fqp_max_p ? cmd->fqp_max_p : 45);
  472. } break;
  473. default : {
  474. mpp_err_f("unsupport encoder rc mode %d\n", p->rc_mode);
  475. } break;
  476. }
  477. } break;
  478. case MPP_VIDEO_CodingVP8 : {
  479. /* vp8 only setup base qp range */
  480. mpp_enc_cfg_set_s32(cfg, "rc:qp_init", cmd->qp_init ? cmd->qp_init : 40);
  481. mpp_enc_cfg_set_s32(cfg, "rc:qp_max", cmd->qp_max ? cmd->qp_max : 127);
  482. mpp_enc_cfg_set_s32(cfg, "rc:qp_min", cmd->qp_min ? cmd->qp_min : 0);
  483. mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", cmd->qp_max_i ? cmd->qp_max_i : 127);
  484. mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", cmd->qp_min_i ? cmd->qp_min_i : 0);
  485. mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 6);
  486. } break;
  487. case MPP_VIDEO_CodingMJPEG : {
  488. /* jpeg use special codec config to control qtable */
  489. mpp_enc_cfg_set_s32(cfg, "jpeg:q_factor", cmd->qp_init ? cmd->qp_init : 80);
  490. mpp_enc_cfg_set_s32(cfg, "jpeg:qf_max", cmd->qp_max ? cmd->qp_max : 99);
  491. mpp_enc_cfg_set_s32(cfg, "jpeg:qf_min", cmd->qp_min ? cmd->qp_min : 1);
  492. } break;
  493. default : {
  494. } break;
  495. }
  496. /* setup codec */
  497. mpp_enc_cfg_set_s32(cfg, "codec:type", p->type);
  498. switch (p->type) {
  499. case MPP_VIDEO_CodingAVC : {
  500. RK_U32 constraint_set;
  501. /*
  502. * H.264 profile_idc parameter
  503. * 66 - Baseline profile
  504. * 77 - Main profile
  505. * 100 - High profile
  506. */
  507. mpp_enc_cfg_set_s32(cfg, "h264:profile", 100);
  508. /*
  509. * H.264 level_idc parameter
  510. * 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
  511. * 20 / 21 / 22 - cif@30fps / half-D1@@25fps / D1@12.5fps
  512. * 30 / 31 / 32 - D1@25fps / 720p@30fps / 720p@60fps
  513. * 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps
  514. * 50 / 51 / 52 - 4K@30fps
  515. */
  516. mpp_enc_cfg_set_s32(cfg, "h264:level", 40);
  517. mpp_enc_cfg_set_s32(cfg, "h264:cabac_en", 1);
  518. mpp_enc_cfg_set_s32(cfg, "h264:cabac_idc", 0);
  519. mpp_enc_cfg_set_s32(cfg, "h264:trans8x8", 1);
  520. mpp_env_get_u32("constraint_set", &constraint_set, 0);
  521. if (constraint_set & 0x3f0000)
  522. mpp_enc_cfg_set_s32(cfg, "h264:constraint_set", constraint_set);
  523. } break;
  524. case MPP_VIDEO_CodingHEVC : {
  525. mpp_enc_cfg_set_s32(cfg, "h265:diff_cu_qp_delta_depth", p->cu_qp_delta_depth);
  526. } break;
  527. case MPP_VIDEO_CodingMJPEG :
  528. case MPP_VIDEO_CodingVP8 : {
  529. } break;
  530. default : {
  531. mpp_err_f("unsupport encoder coding type %d\n", p->type);
  532. } break;
  533. }
  534. p->split_mode = 0;
  535. p->split_arg = 0;
  536. p->split_out = 0;
  537. mpp_env_get_u32("split_mode", &p->split_mode, MPP_ENC_SPLIT_NONE);
  538. mpp_env_get_u32("split_arg", &p->split_arg, 0);
  539. mpp_env_get_u32("split_out", &p->split_out, 0);
  540. if (p->split_mode) {
  541. mpp_log_q(quiet, "%p split mode %d arg %d out %d\n", ctx,
  542. p->split_mode, p->split_arg, p->split_out);
  543. mpp_enc_cfg_set_s32(cfg, "split:mode", p->split_mode);
  544. mpp_enc_cfg_set_s32(cfg, "split:arg", p->split_arg);
  545. mpp_enc_cfg_set_s32(cfg, "split:out", p->split_out);
  546. }
  547. mpp_env_get_u32("mirroring", &mirroring, 0);
  548. mpp_env_get_u32("rotation", &rotation, 0);
  549. mpp_env_get_u32("flip", &flip, 0);
  550. mpp_enc_cfg_set_s32(cfg, "prep:mirroring", mirroring);
  551. mpp_enc_cfg_set_s32(cfg, "prep:rotation", rotation);
  552. mpp_enc_cfg_set_s32(cfg, "prep:flip", flip);
  553. // config gop_len and ref cfg
  554. mpp_enc_cfg_set_s32(cfg, "rc:gop", p->gop_len ? p->gop_len : p->fps_out_num * 2);
  555. mpp_env_get_u32("gop_mode", &gop_mode, gop_mode);
  556. if (gop_mode) {
  557. mpp_enc_ref_cfg_init(&ref);
  558. if (p->gop_mode < 4)
  559. mpi_enc_gen_ref_cfg(ref, gop_mode);
  560. else
  561. mpi_enc_gen_smart_gop_ref_cfg(ref, p->gop_len, p->vi_len);
  562. mpp_enc_cfg_set_ptr(cfg, "rc:ref_cfg", ref);
  563. }
  564. ret = mpi->control(ctx, MPP_ENC_SET_CFG, cfg);
  565. if (ret) {
  566. mpp_err("mpi control enc set cfg failed ret %d\n", ret);
  567. goto RET;
  568. }
  569. if (cmd->type == MPP_VIDEO_CodingAVC || cmd->type == MPP_VIDEO_CodingHEVC) {
  570. RcApiBrief rc_api_brief;
  571. rc_api_brief.type = cmd->type;
  572. rc_api_brief.name = (cmd->rc_mode == MPP_ENC_RC_MODE_SMTRC) ?
  573. "smart" : "default";
  574. ret = mpi->control(ctx, MPP_ENC_SET_RC_API_CURRENT, &rc_api_brief);
  575. if (ret) {
  576. mpp_err("mpi control enc set rc api failed ret %d\n", ret);
  577. goto RET;
  578. }
  579. }
  580. if (ref)
  581. mpp_enc_ref_cfg_deinit(&ref);
  582. /* optional */
  583. {
  584. RK_U32 sei_mode;
  585. mpp_env_get_u32("sei_mode", &sei_mode, MPP_ENC_SEI_MODE_DISABLE);
  586. p->sei_mode = sei_mode;
  587. ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);
  588. if (ret) {
  589. mpp_err("mpi control enc set sei cfg failed ret %d\n", ret);
  590. goto RET;
  591. }
  592. }
  593. if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
  594. p->header_mode = MPP_ENC_HEADER_MODE_EACH_IDR;
  595. ret = mpi->control(ctx, MPP_ENC_SET_HEADER_MODE, &p->header_mode);
  596. if (ret) {
  597. mpp_err("mpi control enc set header mode failed ret %d\n", ret);
  598. goto RET;
  599. }
  600. }
  601. /* setup test mode by env */
  602. mpp_env_get_u32("osd_enable", &p->osd_enable, 0);
  603. mpp_env_get_u32("osd_mode", &p->osd_mode, MPP_ENC_OSD_PLT_TYPE_DEFAULT);
  604. mpp_env_get_u32("roi_enable", &p->roi_enable, 0);
  605. mpp_env_get_u32("user_data_enable", &p->user_data_enable, 0);
  606. if (p->roi_enable) {
  607. mpp_enc_roi_init(&p->roi_ctx, p->width, p->height, p->type, 4);
  608. mpp_assert(p->roi_ctx);
  609. }
  610. RET:
  611. return ret;
  612. }
  613. MPP_RET test_mpp_run(MpiEncMultiCtxInfo *info)
  614. {
  615. MpiEncTestArgs *cmd = info->cmd;
  616. MpiEncTestData *p = &info->ctx;
  617. MppApi *mpi = p->mpi;
  618. MppCtx ctx = p->ctx;
  619. RK_U32 quiet = cmd->quiet;
  620. RK_S32 chn = info->chn;
  621. RK_U32 cap_num = 0;
  622. DataCrc checkcrc;
  623. MPP_RET ret = MPP_OK;
  624. RK_FLOAT psnr_const = 0;
  625. RK_U32 sse_unit_in_pixel = 0;
  626. memset(&checkcrc, 0, sizeof(checkcrc));
  627. checkcrc.sum = mpp_malloc(RK_ULONG, 512);
  628. if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
  629. MppPacket packet = NULL;
  630. /*
  631. * Can use packet with normal malloc buffer as input not pkt_buf.
  632. * Please refer to vpu_api_legacy.cpp for normal buffer case.
  633. * Using pkt_buf buffer here is just for simplifing demo.
  634. */
  635. mpp_packet_init_with_buffer(&packet, p->pkt_buf);
  636. /* NOTE: It is important to clear output packet length!! */
  637. mpp_packet_set_length(packet, 0);
  638. ret = mpi->control(ctx, MPP_ENC_GET_HDR_SYNC, packet);
  639. if (ret) {
  640. mpp_err("mpi control enc get extra info failed\n");
  641. goto RET;
  642. } else {
  643. /* get and write sps/pps for H.264 */
  644. void *ptr = mpp_packet_get_pos(packet);
  645. size_t len = mpp_packet_get_length(packet);
  646. if (p->fp_output)
  647. fwrite(ptr, 1, len, p->fp_output);
  648. }
  649. mpp_packet_deinit(&packet);
  650. sse_unit_in_pixel = p->type == MPP_VIDEO_CodingAVC ? 16 : 8;
  651. psnr_const = (16 + log2(MPP_ALIGN(p->width, sse_unit_in_pixel) *
  652. MPP_ALIGN(p->height, sse_unit_in_pixel)));
  653. }
  654. while (!p->pkt_eos) {
  655. MppMeta meta = NULL;
  656. MppFrame frame = NULL;
  657. MppPacket packet = NULL;
  658. void *buf = mpp_buffer_get_ptr(p->frm_buf);
  659. RK_S32 cam_frm_idx = -1;
  660. MppBuffer cam_buf = NULL;
  661. RK_U32 eoi = 1;
  662. if (p->fp_input) {
  663. mpp_buffer_sync_begin(p->frm_buf);
  664. ret = read_image(buf, p->fp_input, p->width, p->height,
  665. p->hor_stride, p->ver_stride, p->fmt);
  666. if (ret == MPP_NOK || feof(p->fp_input)) {
  667. p->frm_eos = 1;
  668. if (p->frame_num < 0) {
  669. clearerr(p->fp_input);
  670. rewind(p->fp_input);
  671. p->frm_eos = 0;
  672. mpp_log_q(quiet, "chn %d loop times %d\n", chn, ++p->loop_times);
  673. continue;
  674. }
  675. mpp_log_q(quiet, "chn %d found last frame. feof %d\n", chn, feof(p->fp_input));
  676. } else if (ret == MPP_ERR_VALUE)
  677. goto RET;
  678. mpp_buffer_sync_end(p->frm_buf);
  679. } else {
  680. if (p->cam_ctx == NULL) {
  681. mpp_buffer_sync_begin(p->frm_buf);
  682. ret = fill_image(buf, p->width, p->height, p->hor_stride,
  683. p->ver_stride, p->fmt, p->frame_count);
  684. if (ret)
  685. goto RET;
  686. mpp_buffer_sync_end(p->frm_buf);
  687. } else {
  688. cam_frm_idx = camera_source_get_frame(p->cam_ctx);
  689. mpp_assert(cam_frm_idx >= 0);
  690. /* skip unstable frames */
  691. if (cap_num++ < 50) {
  692. camera_source_put_frame(p->cam_ctx, cam_frm_idx);
  693. continue;
  694. }
  695. cam_buf = camera_frame_to_buf(p->cam_ctx, cam_frm_idx);
  696. mpp_assert(cam_buf);
  697. }
  698. }
  699. ret = mpp_frame_init(&frame);
  700. if (ret) {
  701. mpp_err_f("mpp_frame_init failed\n");
  702. goto RET;
  703. }
  704. mpp_frame_set_width(frame, p->width);
  705. mpp_frame_set_height(frame, p->height);
  706. mpp_frame_set_hor_stride(frame, p->hor_stride);
  707. mpp_frame_set_ver_stride(frame, p->ver_stride);
  708. mpp_frame_set_fmt(frame, p->fmt);
  709. mpp_frame_set_eos(frame, p->frm_eos);
  710. if (p->fp_input && feof(p->fp_input))
  711. mpp_frame_set_buffer(frame, NULL);
  712. else if (cam_buf)
  713. mpp_frame_set_buffer(frame, cam_buf);
  714. else
  715. mpp_frame_set_buffer(frame, p->frm_buf);
  716. meta = mpp_frame_get_meta(frame);
  717. mpp_packet_init_with_buffer(&packet, p->pkt_buf);
  718. /* NOTE: It is important to clear output packet length!! */
  719. mpp_packet_set_length(packet, 0);
  720. mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, packet);
  721. mpp_meta_set_buffer(meta, KEY_MOTION_INFO, p->md_info);
  722. if (p->osd_enable || p->user_data_enable || p->roi_enable) {
  723. if (p->user_data_enable) {
  724. MppEncUserData user_data;
  725. char *str = "this is user data\n";
  726. if ((p->frame_count & 10) == 0) {
  727. user_data.pdata = str;
  728. user_data.len = strlen(str) + 1;
  729. mpp_meta_set_ptr(meta, KEY_USER_DATA, &user_data);
  730. }
  731. static RK_U8 uuid_debug_info[16] = {
  732. 0x57, 0x68, 0x97, 0x80, 0xe7, 0x0c, 0x4b, 0x65,
  733. 0xa9, 0x06, 0xae, 0x29, 0x94, 0x11, 0xcd, 0x9a
  734. };
  735. MppEncUserDataSet data_group;
  736. MppEncUserDataFull datas[2];
  737. char *str1 = "this is user data 1\n";
  738. char *str2 = "this is user data 2\n";
  739. data_group.count = 2;
  740. datas[0].len = strlen(str1) + 1;
  741. datas[0].pdata = str1;
  742. datas[0].uuid = uuid_debug_info;
  743. datas[1].len = strlen(str2) + 1;
  744. datas[1].pdata = str2;
  745. datas[1].uuid = uuid_debug_info;
  746. data_group.datas = datas;
  747. mpp_meta_set_ptr(meta, KEY_USER_DATAS, &data_group);
  748. }
  749. if (p->osd_enable) {
  750. /* gen and cfg osd plt */
  751. mpi_enc_gen_osd_plt(&p->osd_plt, p->frame_count);
  752. p->osd_plt_cfg.change = MPP_ENC_OSD_PLT_CFG_CHANGE_ALL;
  753. p->osd_plt_cfg.type = MPP_ENC_OSD_PLT_TYPE_USERDEF;
  754. p->osd_plt_cfg.plt = &p->osd_plt;
  755. ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &p->osd_plt_cfg);
  756. if (ret) {
  757. mpp_err("mpi control enc set osd plt failed ret %d\n", ret);
  758. goto RET;
  759. }
  760. /* gen and cfg osd plt */
  761. mpi_enc_gen_osd_data(&p->osd_data, p->buf_grp, p->width,
  762. p->height, p->frame_count);
  763. mpp_meta_set_ptr(meta, KEY_OSD_DATA, (void*)&p->osd_data);
  764. }
  765. if (p->roi_enable) {
  766. RoiRegionCfg *region = &p->roi_region;
  767. /* calculated in pixels */
  768. region->x = MPP_ALIGN(p->width / 8, 16);
  769. region->y = MPP_ALIGN(p->height / 8, 16);
  770. region->w = 128;
  771. region->h = 256;
  772. region->force_intra = 0;
  773. region->qp_mode = 1;
  774. region->qp_val = 24;
  775. mpp_enc_roi_add_region(p->roi_ctx, region);
  776. region->x = MPP_ALIGN(p->width / 2, 16);
  777. region->y = MPP_ALIGN(p->height / 4, 16);
  778. region->w = 256;
  779. region->h = 128;
  780. region->force_intra = 1;
  781. region->qp_mode = 1;
  782. region->qp_val = 10;
  783. mpp_enc_roi_add_region(p->roi_ctx, region);
  784. /* send roi info by metadata */
  785. mpp_enc_roi_setup_meta(p->roi_ctx, meta);
  786. }
  787. }
  788. if (!p->first_frm)
  789. p->first_frm = mpp_time();
  790. /*
  791. * NOTE: in non-block mode the frame can be resent.
  792. * The default input timeout mode is block.
  793. *
  794. * User should release the input frame to meet the requirements of
  795. * resource creator must be the resource destroyer.
  796. */
  797. ret = mpi->encode_put_frame(ctx, frame);
  798. if (ret) {
  799. mpp_err("chn %d encode put frame failed\n", chn);
  800. mpp_frame_deinit(&frame);
  801. goto RET;
  802. }
  803. mpp_frame_deinit(&frame);
  804. do {
  805. ret = mpi->encode_get_packet(ctx, &packet);
  806. if (ret) {
  807. mpp_err("chn %d encode get packet failed\n", chn);
  808. goto RET;
  809. }
  810. mpp_assert(packet);
  811. if (packet) {
  812. // write packet to file here
  813. void *ptr = mpp_packet_get_pos(packet);
  814. size_t len = mpp_packet_get_length(packet);
  815. char log_buf[256];
  816. RK_S32 log_size = sizeof(log_buf) - 1;
  817. RK_S32 log_len = 0;
  818. if (!p->first_pkt)
  819. p->first_pkt = mpp_time();
  820. p->pkt_eos = mpp_packet_get_eos(packet);
  821. if (p->fp_output)
  822. fwrite(ptr, 1, len, p->fp_output);
  823. if (p->fp_verify && !p->pkt_eos) {
  824. calc_data_crc((RK_U8 *)ptr, (RK_U32)len, &checkcrc);
  825. mpp_log("p->frame_count=%d, len=%d\n", p->frame_count, len);
  826. write_data_crc(p->fp_verify, &checkcrc);
  827. }
  828. log_len += snprintf(log_buf + log_len, log_size - log_len,
  829. "encoded frame %-4d", p->frame_count);
  830. /* for low delay partition encoding */
  831. if (mpp_packet_is_partition(packet)) {
  832. eoi = mpp_packet_is_eoi(packet);
  833. log_len += snprintf(log_buf + log_len, log_size - log_len,
  834. " pkt %d", p->frm_pkt_cnt);
  835. p->frm_pkt_cnt = (eoi) ? (0) : (p->frm_pkt_cnt + 1);
  836. }
  837. log_len += snprintf(log_buf + log_len, log_size - log_len,
  838. " size %-7zu", len);
  839. if (mpp_packet_has_meta(packet)) {
  840. meta = mpp_packet_get_meta(packet);
  841. RK_S32 temporal_id = 0;
  842. RK_S32 lt_idx = -1;
  843. RK_S32 avg_qp = -1, bps_rt = -1;
  844. RK_S32 use_lt_idx = -1;
  845. RK_S64 sse = 0;
  846. RK_FLOAT psnr = 0;
  847. if (MPP_OK == mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, &temporal_id))
  848. log_len += snprintf(log_buf + log_len, log_size - log_len,
  849. " tid %d", temporal_id);
  850. if (MPP_OK == mpp_meta_get_s32(meta, KEY_LONG_REF_IDX, &lt_idx))
  851. log_len += snprintf(log_buf + log_len, log_size - log_len,
  852. " lt %d", lt_idx);
  853. if (MPP_OK == mpp_meta_get_s32(meta, KEY_ENC_AVERAGE_QP, &avg_qp))
  854. log_len += snprintf(log_buf + log_len, log_size - log_len,
  855. " qp %2d", avg_qp);
  856. if (MPP_OK == mpp_meta_get_s32(meta, KEY_ENC_BPS_RT, &bps_rt))
  857. log_len += snprintf(log_buf + log_len, log_size - log_len,
  858. " bps_rt %d", bps_rt);
  859. if (MPP_OK == mpp_meta_get_s32(meta, KEY_ENC_USE_LTR, &use_lt_idx))
  860. log_len += snprintf(log_buf + log_len, log_size - log_len, " vi");
  861. if (MPP_OK == mpp_meta_get_s64(meta, KEY_ENC_SSE, &sse)) {
  862. psnr = 3.01029996 * (psnr_const - log2(sse));
  863. log_len += snprintf(log_buf + log_len, log_size - log_len,
  864. " psnr %.4f", psnr);
  865. }
  866. }
  867. mpp_log_q(quiet, "chn %d %s\n", chn, log_buf);
  868. mpp_packet_deinit(&packet);
  869. fps_calc_inc(cmd->fps);
  870. p->stream_size += len;
  871. p->frame_count += eoi;
  872. if (p->pkt_eos) {
  873. mpp_log_q(quiet, "chn %d found last packet\n", chn);
  874. mpp_assert(p->frm_eos);
  875. }
  876. }
  877. } while (!eoi);
  878. if (cam_frm_idx >= 0)
  879. camera_source_put_frame(p->cam_ctx, cam_frm_idx);
  880. if (p->frame_num > 0 && p->frame_count >= p->frame_num)
  881. break;
  882. if (p->loop_end)
  883. break;
  884. if (p->frm_eos && p->pkt_eos)
  885. break;
  886. }
  887. RET:
  888. MPP_FREE(checkcrc.sum);
  889. return ret;
  890. }
  891. void *enc_test(void *arg)
  892. {
  893. MpiEncMultiCtxInfo *info = (MpiEncMultiCtxInfo *)arg;
  894. MpiEncTestArgs *cmd = info->cmd;
  895. MpiEncTestData *p = &info->ctx;
  896. MpiEncMultiCtxRet *enc_ret = &info->ret;
  897. MppPollType timeout = MPP_POLL_BLOCK;
  898. RK_U32 quiet = cmd->quiet;
  899. MPP_RET ret = MPP_OK;
  900. RK_S64 t_s = 0;
  901. RK_S64 t_e = 0;
  902. mpp_log_q(quiet, "%s start\n", info->name);
  903. ret = test_ctx_init(info);
  904. if (ret) {
  905. mpp_err_f("test data init failed ret %d\n", ret);
  906. goto MPP_TEST_OUT;
  907. }
  908. ret = mpp_buffer_group_get_internal(&p->buf_grp, MPP_BUFFER_TYPE_DRM | MPP_BUFFER_FLAGS_CACHABLE);
  909. if (ret) {
  910. mpp_err_f("failed to get mpp buffer group ret %d\n", ret);
  911. goto MPP_TEST_OUT;
  912. }
  913. ret = mpp_buffer_get(p->buf_grp, &p->frm_buf, p->frame_size + p->header_size);
  914. if (ret) {
  915. mpp_err_f("failed to get buffer for input frame ret %d\n", ret);
  916. goto MPP_TEST_OUT;
  917. }
  918. ret = mpp_buffer_get(p->buf_grp, &p->pkt_buf, p->frame_size);
  919. if (ret) {
  920. mpp_err_f("failed to get buffer for output packet ret %d\n", ret);
  921. goto MPP_TEST_OUT;
  922. }
  923. ret = mpp_buffer_get(p->buf_grp, &p->md_info, p->mdinfo_size);
  924. if (ret) {
  925. mpp_err_f("failed to get buffer for motion info output packet ret %d\n", ret);
  926. goto MPP_TEST_OUT;
  927. }
  928. // encoder demo
  929. ret = mpp_create(&p->ctx, &p->mpi);
  930. if (ret) {
  931. mpp_err("mpp_create failed ret %d\n", ret);
  932. goto MPP_TEST_OUT;
  933. }
  934. mpp_log_q(quiet, "%p encoder test start w %d h %d type %d\n",
  935. p->ctx, p->width, p->height, p->type);
  936. ret = p->mpi->control(p->ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout);
  937. if (MPP_OK != ret) {
  938. mpp_err("mpi control set output timeout %d ret %d\n", timeout, ret);
  939. goto MPP_TEST_OUT;
  940. }
  941. if (cmd->kmpp_en)
  942. kmpp_cfg_init(info);
  943. ret = mpp_init(p->ctx, MPP_CTX_ENC, p->type);
  944. if (ret) {
  945. mpp_err("mpp_init failed ret %d\n", ret);
  946. goto MPP_TEST_OUT;
  947. }
  948. ret = mpp_enc_cfg_init(&p->cfg);
  949. if (ret) {
  950. mpp_err_f("mpp_enc_cfg_init failed ret %d\n", ret);
  951. goto MPP_TEST_OUT;
  952. }
  953. ret = p->mpi->control(p->ctx, MPP_ENC_GET_CFG, p->cfg);
  954. if (ret) {
  955. mpp_err_f("get enc cfg failed ret %d\n", ret);
  956. goto MPP_TEST_OUT;
  957. }
  958. ret = test_mpp_enc_cfg_setup(info);
  959. if (ret) {
  960. mpp_err_f("test mpp setup failed ret %d\n", ret);
  961. goto MPP_TEST_OUT;
  962. }
  963. t_s = mpp_time();
  964. ret = test_mpp_run(info);
  965. t_e = mpp_time();
  966. if (ret) {
  967. mpp_err_f("test mpp run failed ret %d\n", ret);
  968. goto MPP_TEST_OUT;
  969. }
  970. ret = p->mpi->reset(p->ctx);
  971. if (ret) {
  972. mpp_err("mpi->reset failed\n");
  973. goto MPP_TEST_OUT;
  974. }
  975. enc_ret->elapsed_time = t_e - t_s;
  976. enc_ret->frame_count = p->frame_count;
  977. enc_ret->stream_size = p->stream_size;
  978. enc_ret->frame_rate = (float)p->frame_count * 1000000 / enc_ret->elapsed_time;
  979. enc_ret->bit_rate = (p->stream_size * 8 * (p->fps_out_num / p->fps_out_den)) / p->frame_count;
  980. enc_ret->delay = p->first_pkt - p->first_frm;
  981. MPP_TEST_OUT:
  982. if (p->ctx) {
  983. mpp_destroy(p->ctx);
  984. p->ctx = NULL;
  985. }
  986. if (p->cfg) {
  987. mpp_enc_cfg_deinit(p->cfg);
  988. p->cfg = NULL;
  989. }
  990. if (p->frm_buf) {
  991. mpp_buffer_put(p->frm_buf);
  992. p->frm_buf = NULL;
  993. }
  994. if (p->pkt_buf) {
  995. mpp_buffer_put(p->pkt_buf);
  996. p->pkt_buf = NULL;
  997. }
  998. if (p->md_info) {
  999. mpp_buffer_put(p->md_info);
  1000. p->md_info = NULL;
  1001. }
  1002. if (p->osd_data.buf) {
  1003. mpp_buffer_put(p->osd_data.buf);
  1004. p->osd_data.buf = NULL;
  1005. }
  1006. if (p->buf_grp) {
  1007. mpp_buffer_group_put(p->buf_grp);
  1008. p->buf_grp = NULL;
  1009. }
  1010. if (p->roi_ctx) {
  1011. mpp_enc_roi_deinit(p->roi_ctx);
  1012. p->roi_ctx = NULL;
  1013. }
  1014. if (p->init_kcfg)
  1015. kmpp_venc_cfg_deinit(p->init_kcfg);
  1016. test_ctx_deinit(p);
  1017. return NULL;
  1018. }
  1019. int enc_test_multi(MpiEncTestArgs* cmd, const char *name)
  1020. {
  1021. MpiEncMultiCtxInfo *ctxs = NULL;
  1022. float total_rate = 0.0;
  1023. RK_S32 ret = MPP_NOK;
  1024. RK_S32 i = 0;
  1025. ctxs = mpp_calloc(MpiEncMultiCtxInfo, cmd->nthreads);
  1026. if (NULL == ctxs) {
  1027. mpp_err("failed to alloc context for instances\n");
  1028. return -1;
  1029. }
  1030. for (i = 0; i < cmd->nthreads; i++) {
  1031. ctxs[i].cmd = cmd;
  1032. ctxs[i].name = name;
  1033. ctxs[i].chn = i;
  1034. ret = pthread_create(&ctxs[i].thd, NULL, enc_test, &ctxs[i]);
  1035. if (ret) {
  1036. mpp_err("failed to create thread %d\n", i);
  1037. return ret;
  1038. }
  1039. }
  1040. if (cmd->frame_num < 0) {
  1041. // wait for input then quit encoding
  1042. mpp_log("*******************************************\n");
  1043. mpp_log("**** Press Enter to stop loop encoding ****\n");
  1044. mpp_log("*******************************************\n");
  1045. getc(stdin);
  1046. for (i = 0; i < cmd->nthreads; i++)
  1047. ctxs[i].ctx.loop_end = 1;
  1048. }
  1049. for (i = 0; i < cmd->nthreads; i++)
  1050. pthread_join(ctxs[i].thd, NULL);
  1051. for (i = 0; i < cmd->nthreads; i++) {
  1052. MpiEncMultiCtxRet *enc_ret = &ctxs[i].ret;
  1053. mpp_log("chn %d encode %d frames time %lld ms delay %3d ms fps %3.2f bps %lld\n",
  1054. i, enc_ret->frame_count, (RK_S64)(enc_ret->elapsed_time / 1000),
  1055. (RK_S32)(enc_ret->delay / 1000), enc_ret->frame_rate, enc_ret->bit_rate);
  1056. total_rate += enc_ret->frame_rate;
  1057. }
  1058. MPP_FREE(ctxs);
  1059. total_rate /= cmd->nthreads;
  1060. mpp_log("%s average frame rate %.2f\n", name, total_rate);
  1061. return ret;
  1062. }
  1063. int main(int argc, char **argv)
  1064. {
  1065. RK_S32 ret = MPP_NOK;
  1066. MpiEncTestArgs* cmd = mpi_enc_test_cmd_get();
  1067. // parse the cmd option
  1068. ret = mpi_enc_test_cmd_update_by_args(cmd, argc, argv);
  1069. if (ret)
  1070. goto DONE;
  1071. mpi_enc_test_cmd_show_opt(cmd);
  1072. ret = enc_test_multi(cmd, argv[0]);
  1073. DONE:
  1074. mpi_enc_test_cmd_put(cmd);
  1075. return ret;
  1076. }