mpi_rc2_test.c 36 KB

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