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_test"
18
19 #include <string.h>
20 #include "rk_mpi.h"
21
22 #include "mpp_env.h"
23 #include "mpp_mem.h"
24 #include "mpp_time.h"
25 #include "mpp_debug.h"
26 #include "mpp_common.h"
27 #include "securec.h"
28 #include "utils_mpp.h"
29 #include "mpi_enc_utils.h"
30 //#include "camera.h"
31
test_ctx_init(MpiEncMultiCtxInfo *info)32 MPP_RET test_ctx_init(MpiEncMultiCtxInfo *info)
33 {
34 MpiEncTestArgs *cmd = info->cmd;
35 MpiEncTestData *p = &info->ctx;
36 MPP_RET ret = MPP_OK;
37
38 // get paramter from cmd
39 p->width = cmd->width;
40 p->height = cmd->height;
41 p->hor_stride = (cmd->hor_stride) ? (cmd->hor_stride) :
42 (MPP_ALIGN(cmd->width, 16));
43 p->ver_stride = (cmd->ver_stride) ? (cmd->ver_stride) :
44 (MPP_ALIGN(cmd->height, 16));
45 p->fmt = cmd->format;
46 p->type = cmd->type;
47 p->bps = cmd->bps_target;
48 p->bps_min = cmd->bps_min;
49 p->bps_max = cmd->bps_max;
50 p->rc_mode = cmd->rc_mode;
51 p->frame_num = cmd->frame_num;
52 if (cmd->type == MPP_VIDEO_CodingMJPEG && p->frame_num == 0) {
53 mpp_log("jpege default encode only one frame. Use -n [num] for rc case\n");
54 p->frame_num = 1;
55 }
56 p->gop_mode = cmd->gop_mode;
57 p->gop_len = cmd->gop_len;
58 p->vi_len = cmd->vi_len;
59
60 p->fps_in_flex = cmd->fps_in_flex;
61 p->fps_in_den = cmd->fps_in_den;
62 p->fps_in_num = cmd->fps_in_num;
63 p->fps_out_flex = cmd->fps_out_flex;
64 p->fps_out_den = cmd->fps_out_den;
65 p->fps_out_num = cmd->fps_out_num;
66 p->mdinfo_size = (MPP_VIDEO_CodingHEVC == cmd->type) ?
67 (MPP_ALIGN(p->hor_stride, 64) >> 6) *
68 (MPP_ALIGN(p->ver_stride, 64) >> 6) * 32 :
69 (MPP_ALIGN(p->hor_stride, 64) >> 6) *
70 (MPP_ALIGN(p->ver_stride, 16) >> 4) * 8;
71
72 if (cmd->file_input) {
73 if (!strncmp(cmd->file_input, "/dev/video", 10)) {
74 mpp_log("open camera device");
75 p->cam_ctx = camera_source_init(cmd->file_input, 4, p->width, p->height, p->fmt);
76 mpp_log("new framecap ok");
77 if (p->cam_ctx == NULL)
78 mpp_err("open %s fail", cmd->file_input);
79 } else {
80 p->fp_input = fopen(cmd->file_input, "rb");
81 if (NULL == p->fp_input) {
82 mpp_err("failed to open input file %s\n", cmd->file_input);
83 mpp_err("create default yuv image for test\n");
84 }
85 }
86 }
87
88 if (cmd->file_output) {
89 p->fp_output = fopen(cmd->file_output, "w+b");
90 if (NULL == p->fp_output) {
91 mpp_err("failed to open output file %s\n", cmd->file_output);
92 ret = MPP_ERR_OPEN_FILE;
93 }
94 }
95
96 p->fp_output = fopen("/data/genan.h264", "w+b");
97
98 if (cmd->file_slt) {
99 p->fp_verify = fopen(cmd->file_slt, "wt");
100 if (!p->fp_verify)
101 mpp_err("failed to open verify file %s\n", cmd->file_slt);
102 }
103
104 // update resource parameter
105 switch (p->fmt & MPP_FRAME_FMT_MASK) {
106 case MPP_FMT_YUV420SP:
107 case MPP_FMT_YUV420P: {
108 p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 3 / 2;
109 } break;
110
111 case MPP_FMT_YUV422_YUYV :
112 case MPP_FMT_YUV422_YVYU :
113 case MPP_FMT_YUV422_UYVY :
114 case MPP_FMT_YUV422_VYUY :
115 case MPP_FMT_YUV422P :
116 case MPP_FMT_YUV422SP : {
117 p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 2;
118 } break;
119 case MPP_FMT_RGB444 :
120 case MPP_FMT_BGR444 :
121 case MPP_FMT_RGB555 :
122 case MPP_FMT_BGR555 :
123 case MPP_FMT_RGB565 :
124 case MPP_FMT_BGR565 :
125 case MPP_FMT_RGB888 :
126 case MPP_FMT_BGR888 :
127 case MPP_FMT_RGB101010 :
128 case MPP_FMT_BGR101010 :
129 case MPP_FMT_ARGB8888 :
130 case MPP_FMT_ABGR8888 :
131 case MPP_FMT_BGRA8888 :
132 case MPP_FMT_RGBA8888 : {
133 p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64);
134 } break;
135
136 default: {
137 p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 4;
138 } break;
139 }
140
141 if (MPP_FRAME_FMT_IS_FBC(p->fmt)) {
142 if ((p->fmt & MPP_FRAME_FBC_MASK) == MPP_FRAME_FBC_AFBC_V1)
143 p->header_size = MPP_ALIGN(MPP_ALIGN(p->width, 16) * MPP_ALIGN(p->height, 16) / 16, SZ_4K);
144 else
145 p->header_size = MPP_ALIGN(p->width, 16) * MPP_ALIGN(p->height, 16) / 16;
146 } else {
147 p->header_size = 0;
148 }
149
150 return ret;
151 }
152
test_ctx_deinit(MpiEncTestData *p)153 MPP_RET test_ctx_deinit(MpiEncTestData *p)
154 {
155 if (p) {
156 if (p->cam_ctx) {
157 camera_source_deinit(p->cam_ctx);
158 p->cam_ctx = NULL;
159 }
160 if (p->fp_input) {
161 fclose(p->fp_input);
162 p->fp_input = NULL;
163 }
164 if (p->fp_output) {
165 fclose(p->fp_output);
166 p->fp_output = NULL;
167 }
168 if (p->fp_verify) {
169 fclose(p->fp_verify);
170 p->fp_verify = NULL;
171 }
172 }
173 return MPP_OK;
174 }
175
test_mpp_enc_cfg_setup(MpiEncMultiCtxInfo *info)176 MPP_RET test_mpp_enc_cfg_setup(MpiEncMultiCtxInfo *info)
177 {
178 MpiEncTestArgs *cmd = info->cmd;
179 MpiEncTestData *p = &info->ctx;
180 MppApi *mpi = p->mpi;
181 MppCtx ctx = p->ctx;
182 MppEncCfg cfg = p->cfg;
183 RK_U32 quiet = cmd->quiet;
184 MPP_RET ret;
185
186 /* setup default parameter */
187 if (p->fps_in_den == 0)
188 p->fps_in_den = 1;
189 if (p->fps_in_num == 0)
190 p->fps_in_num = 30;
191 if (p->fps_out_den == 0)
192 p->fps_out_den = 1;
193 if (p->fps_out_num == 0)
194 p->fps_out_num = 30;
195
196 if (!p->bps)
197 p->bps = p->width * p->height / 8 * (p->fps_out_num / p->fps_out_den);
198
199 mpp_enc_cfg_set_s32(cfg, "prep:width", p->width);
200 mpp_enc_cfg_set_s32(cfg, "prep:height", p->height);
201 mpp_enc_cfg_set_s32(cfg, "prep:hor_stride", p->hor_stride);
202 mpp_enc_cfg_set_s32(cfg, "prep:ver_stride", p->ver_stride);
203 mpp_enc_cfg_set_s32(cfg, "prep:format", p->fmt);
204
205 mpp_enc_cfg_set_s32(cfg, "rc:mode", p->rc_mode);
206
207 /* fix input / output frame rate */
208 mpp_enc_cfg_set_s32(cfg, "rc:fps_in_flex", p->fps_in_flex);
209 mpp_enc_cfg_set_s32(cfg, "rc:fps_in_num", p->fps_in_num);
210 mpp_enc_cfg_set_s32(cfg, "rc:fps_in_denorm", p->fps_in_den);
211 mpp_enc_cfg_set_s32(cfg, "rc:fps_out_flex", p->fps_out_flex);
212 mpp_enc_cfg_set_s32(cfg, "rc:fps_out_num", p->fps_out_num);
213 mpp_enc_cfg_set_s32(cfg, "rc:fps_out_denorm", p->fps_out_den);
214 mpp_enc_cfg_set_s32(cfg, "rc:gop", p->gop_len ? p->gop_len : p->fps_out_num * 2);
215
216 /* drop frame or not when bitrate overflow */
217 mpp_enc_cfg_set_u32(cfg, "rc:drop_mode", MPP_ENC_RC_DROP_FRM_DISABLED);
218 mpp_enc_cfg_set_u32(cfg, "rc:drop_thd", 20); /* 20% of max bps */
219 mpp_enc_cfg_set_u32(cfg, "rc:drop_gap", 1); /* Do not continuous drop frame */
220
221 /* setup bitrate for different rc_mode */
222 mpp_enc_cfg_set_s32(cfg, "rc:bps_target", p->bps);
223 switch (p->rc_mode) {
224 case MPP_ENC_RC_MODE_FIXQP : {
225 /* do not setup bitrate on FIXQP mode */
226 } break;
227 case MPP_ENC_RC_MODE_CBR : {
228 /* CBR mode has narrow bound */
229 mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
230 mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
231 } break;
232 case MPP_ENC_RC_MODE_VBR :
233 case MPP_ENC_RC_MODE_AVBR : {
234 /* VBR mode has wide bound */
235 mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
236 mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 1 / 16);
237 } break;
238 default : {
239 /* default use CBR mode */
240 mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
241 mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
242 } break;
243 }
244
245 /* setup qp for different codec and rc_mode */
246 switch (p->type) {
247 case MPP_VIDEO_CodingAVC :
248 case MPP_VIDEO_CodingHEVC : {
249 switch (p->rc_mode) {
250 case MPP_ENC_RC_MODE_FIXQP : {
251 RK_S32 fix_qp = cmd->qp_init;
252
253 mpp_enc_cfg_set_s32(cfg, "rc:qp_init", fix_qp);
254 mpp_enc_cfg_set_s32(cfg, "rc:qp_max", fix_qp);
255 mpp_enc_cfg_set_s32(cfg, "rc:qp_min", fix_qp);
256 mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", fix_qp);
257 mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", fix_qp);
258 mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 0);
259 } break;
260 case MPP_ENC_RC_MODE_CBR :
261 case MPP_ENC_RC_MODE_VBR :
262 case MPP_ENC_RC_MODE_AVBR : {
263 mpp_enc_cfg_set_s32(cfg, "rc:qp_init", -1);
264 mpp_enc_cfg_set_s32(cfg, "rc:qp_max", 51);
265 mpp_enc_cfg_set_s32(cfg, "rc:qp_min", 10);
266 mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", 51);
267 mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", 10);
268 mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 2);
269 } break;
270 default : {
271 mpp_err_f("unsupport encoder rc mode %d\n", p->rc_mode);
272 } break;
273 }
274 } break;
275 case MPP_VIDEO_CodingVP8 : {
276 /* vp8 only setup base qp range */
277 mpp_enc_cfg_set_s32(cfg, "rc:qp_init", 40);
278 mpp_enc_cfg_set_s32(cfg, "rc:qp_max", 127);
279 mpp_enc_cfg_set_s32(cfg, "rc:qp_min", 0);
280 mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", 127);
281 mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", 0);
282 mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 6);
283 } break;
284 case MPP_VIDEO_CodingMJPEG : {
285 /* jpeg use special codec config to control qtable */
286 mpp_enc_cfg_set_s32(cfg, "jpeg:q_factor", 80);
287 mpp_enc_cfg_set_s32(cfg, "jpeg:qf_max", 99);
288 mpp_enc_cfg_set_s32(cfg, "jpeg:qf_min", 1);
289 } break;
290 default : {
291 } break;
292 }
293
294 /* setup codec */
295 mpp_enc_cfg_set_s32(cfg, "codec:type", p->type);
296 switch (p->type) {
297 case MPP_VIDEO_CodingAVC : {
298 /*
299 * H.264 profile_idc parameter
300 * 66 - Baseline profile
301 * 77 - Main profile
302 * 100 - High profile
303 */
304 mpp_enc_cfg_set_s32(cfg, "h264:profile", 100);
305 /*
306 * H.264 level_idc parameter
307 * 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
308 * 20 / 21 / 22 - cif@30fps / half-D1@@25fps / D1@12.5fps
309 * 30 / 31 / 32 - D1@25fps / 720p@30fps / 720p@60fps
310 * 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps
311 * 50 / 51 / 52 - 4K@30fps
312 */
313 mpp_enc_cfg_set_s32(cfg, "h264:level", 40);
314 mpp_enc_cfg_set_s32(cfg, "h264:cabac_en", 1);
315 mpp_enc_cfg_set_s32(cfg, "h264:cabac_idc", 0);
316 mpp_enc_cfg_set_s32(cfg, "h264:trans8x8", 1);
317 } break;
318 case MPP_VIDEO_CodingHEVC :
319 case MPP_VIDEO_CodingMJPEG :
320 case MPP_VIDEO_CodingVP8 : {
321 } break;
322 default : {
323 mpp_err_f("unsupport encoder coding type %d\n", p->type);
324 } break;
325 }
326
327 p->split_mode = 0;
328 p->split_arg = 0;
329 p->split_out = 0;
330
331 mpp_env_get_u32("split_mode", &p->split_mode, MPP_ENC_SPLIT_NONE);
332 mpp_env_get_u32("split_arg", &p->split_arg, 0);
333 mpp_env_get_u32("split_out", &p->split_out, 0);
334
335 if (p->split_mode) {
336 mpp_log_q(quiet, "%p split mode %d arg %d out %d\n", ctx,
337 p->split_mode, p->split_arg, p->split_out);
338 mpp_enc_cfg_set_s32(cfg, "split:mode", p->split_mode);
339 mpp_enc_cfg_set_s32(cfg, "split:arg", p->split_arg);
340 mpp_enc_cfg_set_s32(cfg, "split:out", p->split_out);
341 }
342
343 ret = mpi->control(ctx, MPP_ENC_SET_CFG, cfg);
344 if (ret) {
345 mpp_err("mpi control enc set cfg failed ret %d\n", ret);
346 goto RET;
347 }
348
349 /* optional */
350 p->sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME;
351 ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);
352 if (ret) {
353 mpp_err("mpi control enc set sei cfg failed ret %d\n", ret);
354 goto RET;
355 }
356
357 if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
358 p->header_mode = MPP_ENC_HEADER_MODE_EACH_IDR;
359 ret = mpi->control(ctx, MPP_ENC_SET_HEADER_MODE, &p->header_mode);
360 if (ret) {
361 mpp_err("mpi control enc set header mode failed ret %d\n", ret);
362 goto RET;
363 }
364 }
365
366 RK_U32 gop_mode = p->gop_mode;
367
368 mpp_env_get_u32("gop_mode", &gop_mode, gop_mode);
369 if (gop_mode) {
370 MppEncRefCfg ref;
371
372 mpp_enc_ref_cfg_init(&ref);
373
374 if (p->gop_mode < 4)
375 mpi_enc_gen_ref_cfg(ref, gop_mode);
376 else
377 mpi_enc_gen_smart_gop_ref_cfg(ref, p->gop_len, p->vi_len);
378
379 ret = mpi->control(ctx, MPP_ENC_SET_REF_CFG, ref);
380 if (ret) {
381 mpp_err("mpi control enc set ref cfg failed ret %d\n", ret);
382 goto RET;
383 }
384 mpp_enc_ref_cfg_deinit(&ref);
385 }
386
387 /* setup test mode by env */
388 mpp_env_get_u32("osd_enable", &p->osd_enable, 0);
389 mpp_env_get_u32("osd_mode", &p->osd_mode, MPP_ENC_OSD_PLT_TYPE_DEFAULT);
390 mpp_env_get_u32("roi_enable", &p->roi_enable, 0);
391 mpp_env_get_u32("user_data_enable", &p->user_data_enable, 0);
392
393 if (p->roi_enable) {
394 mpp_enc_roi_init(&p->roi_ctx, p->width, p->height, p->type, 4);
395 mpp_assert(p->roi_ctx);
396 }
397
398 RET:
399 return ret;
400 }
401
hal_mpp_get_sps(void *ctxs, unsigned char *buf, size_t *buf_size)402 int hal_mpp_get_sps(void *ctxs, unsigned char *buf, size_t *buf_size)
403 {
404 MpiEncTestData *p = &((MpiEncMultiCtxInfo *)ctxs)->ctx;
405 MppApi *mpi = p->mpi;
406 MppCtx ctx = p->ctx;
407 int ret;
408
409 if (!p) {
410 mpp_err("mpi control enc get extra info failed\n");
411 return MPP_NOK;
412 }
413
414 if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
415 MppPacket packet = NULL;
416
417 /*
418 * Can use packet with normal malloc buffer as input not pkt_buf.
419 * Please refer to vpu_api_legacy.cpp for normal buffer case.
420 * Using pkt_buf buffer here is just for simplifing demo.
421 */
422 mpp_packet_init_with_buffer(&packet, p->pkt_buf);
423 /* NOTE: It is important to clear output packet length!! */
424 mpp_packet_set_length(packet, 0);
425
426 ret = mpi->control(ctx, MPP_ENC_GET_HDR_SYNC, packet);
427 if (ret) {
428 mpp_err("mpi control enc get extra info failed\n");
429 return MPP_NOK;
430 } else {
431 /* get and write sps/pps for H.264 */
432 void *ptr = mpp_packet_get_pos(packet);
433 size_t len = mpp_packet_get_length(packet);
434
435 if (*buf_size < len) {
436 mpp_err("mpi buffer size too small\n");
437 ret = MPP_NOK;
438 mpp_packet_deinit(&packet);
439 return ret;
440 }
441
442 errno_t eok = memcpy_s(buf, len, ptr, len);
443 if (eok != EOK) {
444 mpp_err("memcpy_s failed\n");
445 return MPP_NOK;
446 }
447
448 *buf_size = len;
449
450 }
451 mpp_packet_deinit(&packet);
452 }
453
454 ret = MPP_OK;
455 return ret;
456 }
457
hal_mpp_encode(void *ctxs, int dma_fd, unsigned char *buf, size_t *buf_size)458 int hal_mpp_encode(void *ctxs, int dma_fd, unsigned char *buf, size_t *buf_size)
459 {
460 MpiEncMultiCtxInfo *info = (MpiEncMultiCtxInfo *)ctxs;
461 MpiEncTestArgs *cmd = info->cmd;
462 MpiEncMultiCtxRet *enc_ret = &info->ret;
463 MpiEncTestData *p = &info->ctx;
464 MppApi *mpi = p->mpi;
465 MppCtx ctx = p->ctx;
466 RK_U32 quiet = cmd->quiet;
467 RK_S32 chn = info->chn;
468 DataCrc checkcrc;
469 RK_S64 t_s = 0;
470 RK_S64 t_e = 0;
471 size_t bufPos = 0;
472
473 t_s = mpp_time();
474
475 MppBuffer hbuf = NULL;
476 MppBufferInfo inf;
477 memset(&inf, 0, sizeof(MppBufferInfo));
478 inf.type = MPP_BUFFER_TYPE_EXT_DMA;
479 inf.fd = dma_fd;
480 inf.size = p->frame_size & 0x07ffffff;
481 inf.index = (p->frame_size & 0xf8000000) >> 27;
482 mpp_buffer_import(&hbuf, &inf);
483
484 memset(&checkcrc, 0, sizeof(checkcrc));
485 checkcrc.sum = mpp_malloc(RK_ULONG, 512);
486
487 //while (!p->pkt_eos) {
488 MppMeta meta = NULL;
489 MppFrame frame = NULL;
490 MppPacket packet = NULL;
491 RK_U32 eoi = 1;
492
493 MPP_RET ret = mpp_frame_init(&frame);
494 if (ret) {
495 mpp_err_f("mpp_frame_init failed\n");
496 goto RET;
497 }
498
499 mpp_frame_set_width(frame, p->width);
500 mpp_frame_set_height(frame, p->height);
501 mpp_frame_set_hor_stride(frame, p->hor_stride);
502 mpp_frame_set_ver_stride(frame, p->ver_stride);
503 mpp_frame_set_fmt(frame, p->fmt);
504 mpp_frame_set_eos(frame, p->frm_eos);
505
506 //mpp_frame_set_buffer(frame, p->frm_buf);
507 mpp_frame_set_buffer(frame, hbuf);
508
509 meta = mpp_frame_get_meta(frame);
510 mpp_packet_init_with_buffer(&packet, p->pkt_buf);
511 /* NOTE: It is important to clear output packet length!! */
512 mpp_packet_set_length(packet, 0);
513 mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, packet);
514 mpp_meta_set_buffer(meta, KEY_MOTION_INFO, p->md_info);
515
516 if (p->osd_enable || p->user_data_enable || p->roi_enable) {
517 if (p->user_data_enable) {
518 MppEncUserData user_data;
519 char *str = "this is user data\n";
520
521 if ((p->frame_count & 10) == 0) {
522 user_data.pdata = str;
523 user_data.len = strlen(str) + 1;
524 mpp_meta_set_ptr(meta, KEY_USER_DATA, &user_data);
525 }
526 static RK_U8 uuid_debug_info[16] = {
527 0x57, 0x68, 0x97, 0x80, 0xe7, 0x0c, 0x4b, 0x65,
528 0xa9, 0x06, 0xae, 0x29, 0x94, 0x11, 0xcd, 0x9a
529 };
530
531 MppEncUserDataSet data_group;
532 MppEncUserDataFull datas[2];
533 char *str1 = "this is user data 1\n";
534 char *str2 = "this is user data 2\n";
535 data_group.count = 2;
536 datas[0].len = strlen(str1) + 1;
537 datas[0].pdata = str1;
538 datas[0].uuid = uuid_debug_info;
539
540 datas[1].len = strlen(str2) + 1;
541 datas[1].pdata = str2;
542 datas[1].uuid = uuid_debug_info;
543
544 data_group.datas = datas;
545
546 mpp_meta_set_ptr(meta, KEY_USER_DATAS, &data_group);
547 }
548
549 if (p->osd_enable) {
550 /* gen and cfg osd plt */
551 mpi_enc_gen_osd_plt(&p->osd_plt, p->frame_count);
552
553 p->osd_plt_cfg.change = MPP_ENC_OSD_PLT_CFG_CHANGE_ALL;
554 p->osd_plt_cfg.type = MPP_ENC_OSD_PLT_TYPE_USERDEF;
555 p->osd_plt_cfg.plt = &p->osd_plt;
556
557 ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &p->osd_plt_cfg);
558 if (ret) {
559 mpp_err("mpi control enc set osd plt failed ret %d\n", ret);
560 goto RET;
561 }
562
563 /* gen and cfg osd plt */
564 mpi_enc_gen_osd_data(&p->osd_data, p->buf_grp, p->width,
565 p->height, p->frame_count);
566 mpp_meta_set_ptr(meta, KEY_OSD_DATA, (void*)&p->osd_data);
567 }
568
569 if (p->roi_enable) {
570 RoiRegionCfg *region = &p->roi_region;
571
572 /* calculated in pixels */
573 region->x = MPP_ALIGN(p->width / 8, 16);
574 region->y = MPP_ALIGN(p->height / 8, 16);
575 region->w = 128;
576 region->h = 256;
577 region->force_intra = 0;
578 region->qp_mode = 1;
579 region->qp_val = 24;
580
581 mpp_enc_roi_add_region(p->roi_ctx, region);
582
583 region->x = MPP_ALIGN(p->width / 2, 16);
584 region->y = MPP_ALIGN(p->height / 4, 16);
585 region->w = 256;
586 region->h = 128;
587 region->force_intra = 1;
588 region->qp_mode = 1;
589 region->qp_val = 10;
590
591 mpp_enc_roi_add_region(p->roi_ctx, region);
592
593 /* send roi info by metadata */
594 mpp_enc_roi_setup_meta(p->roi_ctx, meta);
595 }
596 }
597
598 if (!p->first_frm)
599 p->first_frm = mpp_time();
600 /*
601 * NOTE: in non-block mode the frame can be resent.
602 * The default input timeout mode is block.
603 *
604 * User should release the input frame to meet the requirements of
605 * resource creator must be the resource destroyer.
606 */
607 ret = mpi->encode_put_frame(ctx, frame);
608 if (ret) {
609 mpp_err("chn %d encode put frame failed\n", chn);
610 mpp_frame_deinit(&frame);
611 if (hbuf) {
612 mpp_buffer_put(hbuf);
613 }
614 goto RET;
615 }
616
617 mpp_frame_deinit(&frame);
618
619 do {
620 ret = mpi->encode_get_packet(ctx, &packet);
621 if (ret) {
622 if (hbuf) {
623 mpp_buffer_put(hbuf);
624 }
625 mpp_err("chn %d encode get packet failed\n", chn);
626 goto RET;
627 }
628 mpp_assert(packet);
629
630 if (packet) {
631 // write packet to file here
632 void *ptr = mpp_packet_get_pos(packet);
633 size_t len = mpp_packet_get_length(packet);
634 memcpy_s(&buf[bufPos], len, ptr, len);
635 bufPos += len;
636 char log_buf[256];
637 RK_S32 log_size = sizeof(log_buf) - 1;
638 RK_S32 log_len = 0;
639
640 if (!p->first_pkt)
641 p->first_pkt = mpp_time();
642
643 p->pkt_eos = mpp_packet_get_eos(packet);
644 if (p->fp_output)
645 fwrite(ptr, 1, len, p->fp_output);
646
647 log_len += snprintf(log_buf + log_len, log_size - log_len,
648 "encoded frame %-4d", p->frame_count);
649
650 /* for low delay partition encoding */
651 if (mpp_packet_is_partition(packet)) {
652 eoi = mpp_packet_is_eoi(packet);
653
654 log_len += snprintf(log_buf + log_len, log_size - log_len,
655 " pkt %d", p->frm_pkt_cnt);
656 p->frm_pkt_cnt = (eoi) ? (0) : (p->frm_pkt_cnt + 1);
657 }
658
659 log_len += snprintf(log_buf + log_len, log_size - log_len,
660 " size %-7zu", len);
661
662 if (mpp_packet_has_meta(packet)) {
663 meta = mpp_packet_get_meta(packet);
664 RK_S32 temporal_id = 0;
665 RK_S32 lt_idx = -1;
666 RK_S32 avg_qp = -1;
667
668 if (MPP_OK == mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, &temporal_id))
669 log_len += snprintf(log_buf + log_len, log_size - log_len,
670 " tid %d", temporal_id);
671
672 if (MPP_OK == mpp_meta_get_s32(meta, KEY_LONG_REF_IDX, <_idx))
673 log_len += snprintf(log_buf + log_len, log_size - log_len,
674 " lt %d", lt_idx);
675
676 if (MPP_OK == mpp_meta_get_s32(meta, KEY_ENC_AVERAGE_QP, &avg_qp))
677 log_len += snprintf(log_buf + log_len, log_size - log_len,
678 " qp %d", avg_qp);
679 }
680
681 mpp_log_q(quiet, "chn %d %s\n", chn, log_buf);
682
683 //mpp_packet_deinit(&packet);
684 fps_calc_inc(cmd->fps);
685
686 p->stream_size += len;
687 p->frame_count += eoi;
688
689 if (p->pkt_eos) {
690 mpp_log_q(quiet, "chn %d found last packet\n", chn);
691 mpp_assert(p->frm_eos);
692 }
693 }
694 } while (!eoi);
695
696 RET:
697 MPP_FREE(checkcrc.sum);
698 t_e = mpp_time();
699
700 if (hbuf) {
701 mpp_buffer_put(hbuf);
702 }
703 mpp_packet_deinit(&packet);
704
705 enc_ret->elapsed_time = t_e - t_s;
706 enc_ret->frame_count = p->frame_count;
707 enc_ret->stream_size = p->stream_size;
708 enc_ret->frame_rate = (float)p->frame_count * 1000000 / enc_ret->elapsed_time;
709 enc_ret->bit_rate = (p->stream_size * 8 * (p->fps_out_num / p->fps_out_den)) / p->frame_count;
710 enc_ret->delay = p->first_pkt - p->first_frm;
711
712 *buf_size = bufPos;
713
714 return ret;
715 }
716
hal_mpp_ctx_delete(void *ctx)717 void hal_mpp_ctx_delete(void *ctx)
718 {
719 MpiEncMultiCtxInfo *info = (MpiEncMultiCtxInfo *)ctx;
720 MpiEncTestData *p = &info->ctx;
721 MpiEncTestArgs* cmd = info->cmd;
722 int ret = 0;
723
724 ret = p->mpi->reset(p->ctx);
725 if (ret) {
726 mpp_err("mpi->reset failed\n");
727 }
728
729 if (p->ctx) {
730 mpp_destroy(p->ctx);
731 p->ctx = NULL;
732 }
733
734 if (p->cfg) {
735 mpp_enc_cfg_deinit(p->cfg);
736 p->cfg = NULL;
737 }
738
739 if (p->frm_buf) {
740 mpp_buffer_put(p->frm_buf);
741 p->frm_buf = NULL;
742 }
743
744 if (p->pkt_buf) {
745 mpp_buffer_put(p->pkt_buf);
746 p->pkt_buf = NULL;
747 }
748
749 if (p->md_info) {
750 mpp_buffer_put(p->md_info);
751 p->md_info = NULL;
752 }
753
754 if (p->osd_data.buf) {
755 mpp_buffer_put(p->osd_data.buf);
756 p->osd_data.buf = NULL;
757 }
758
759 if (p->buf_grp) {
760 mpp_buffer_group_put(p->buf_grp);
761 p->buf_grp = NULL;
762 }
763
764 if (p->roi_ctx) {
765 mpp_enc_roi_deinit(p->roi_ctx);
766 p->roi_ctx = NULL;
767 }
768
769 test_ctx_deinit(p);
770 MPP_FREE(info);
771
772 if (NULL == cmd)
773 return;
774
775 if (cmd->cfg_ini) {
776 iniparser_freedict(cmd->cfg_ini);
777 cmd->cfg_ini = NULL;
778 }
779
780 if (cmd->fps) {
781 fps_calc_deinit(cmd->fps);
782 cmd->fps = NULL;
783 }
784 MPP_FREE(cmd);
785
786 return;
787 }
788
hal_mpp_ctx_create(MpiEncTestArgs *args)789 void *hal_mpp_ctx_create(MpiEncTestArgs *args)
790 {
791 MpiEncMultiCtxInfo *ctxs = mpp_calloc(MpiEncMultiCtxInfo, args->nthreads);
792 if (NULL == ctxs) {
793 mpp_err("failed to alloc context for instances\n");
794 return NULL;
795 }
796 ctxs[0].cmd = args;
797 ctxs[0].chn = 0;
798 ctxs[0].name = "rk_camera";
799
800 MpiEncMultiCtxInfo *info = ctxs;
801 MpiEncTestArgs *cmd = info->cmd;
802 MpiEncTestData *p = &info->ctx;
803 MppPollType timeout = MPP_POLL_BLOCK;
804 RK_U32 quiet = cmd->quiet;
805
806 MPP_RET ret = test_ctx_init(info);
807 if (ret) {
808 mpp_err_f("test data init failed ret %d\n", ret);
809 goto MPP_TEST_OUT;
810 }
811
812 ret = mpp_buffer_group_get_internal(&p->buf_grp, MPP_BUFFER_TYPE_DRM);
813 if (ret) {
814 mpp_err_f("failed to get mpp buffer group ret %d\n", ret);
815 goto MPP_TEST_OUT;
816 }
817
818 ret = mpp_buffer_get(p->buf_grp, &p->frm_buf, p->frame_size + p->header_size);
819 if (ret) {
820 mpp_err_f("failed to get buffer for input frame ret %d\n", ret);
821 goto MPP_TEST_OUT;
822 }
823
824 ret = mpp_buffer_get(p->buf_grp, &p->pkt_buf, p->frame_size);
825 if (ret) {
826 mpp_err_f("failed to get buffer for output packet ret %d\n", ret);
827 goto MPP_TEST_OUT;
828 }
829
830 ret = mpp_buffer_get(p->buf_grp, &p->md_info, p->mdinfo_size);
831 if (ret) {
832 mpp_err_f("failed to get buffer for motion info output packet ret %d\n", ret);
833 goto MPP_TEST_OUT;
834 }
835
836 // encoder demo
837 ret = mpp_create(&p->ctx, &p->mpi);
838 if (ret) {
839 mpp_err("mpp_create failed ret %d\n", ret);
840 goto MPP_TEST_OUT;
841 }
842
843 mpp_log_q(quiet, "%p encoder test start w %d h %d type %d\n",
844 p->ctx, p->width, p->height, p->type);
845
846 ret = p->mpi->control(p->ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout);
847 if (MPP_OK != ret) {
848 mpp_err("mpi control set output timeout %d ret %d\n", timeout, ret);
849 goto MPP_TEST_OUT;
850 }
851
852 ret = mpp_init(p->ctx, MPP_CTX_ENC, p->type);
853 if (ret) {
854 mpp_err("mpp_init failed ret %d\n", ret);
855 goto MPP_TEST_OUT;
856 }
857
858 ret = mpp_enc_cfg_init(&p->cfg);
859 if (ret) {
860 mpp_err_f("mpp_enc_cfg_init failed ret %d\n", ret);
861 goto MPP_TEST_OUT;
862 }
863
864 ret = test_mpp_enc_cfg_setup(info);
865 if (ret) {
866 mpp_err_f("test mpp setup failed ret %d\n", ret);
867 goto MPP_TEST_OUT;
868 }
869
870 return info;
871
872 MPP_TEST_OUT:
873 if (p->ctx) {
874 mpp_destroy(p->ctx);
875 p->ctx = NULL;
876 }
877
878 if (p->cfg) {
879 mpp_enc_cfg_deinit(p->cfg);
880 p->cfg = NULL;
881 }
882
883 if (p->frm_buf) {
884 mpp_buffer_put(p->frm_buf);
885 p->frm_buf = NULL;
886 }
887
888 if (p->pkt_buf) {
889 mpp_buffer_put(p->pkt_buf);
890 p->pkt_buf = NULL;
891 }
892
893 if (p->md_info) {
894 mpp_buffer_put(p->md_info);
895 p->md_info = NULL;
896 }
897
898 if (p->osd_data.buf) {
899 mpp_buffer_put(p->osd_data.buf);
900 p->osd_data.buf = NULL;
901 }
902
903 if (p->buf_grp) {
904 mpp_buffer_group_put(p->buf_grp);
905 p->buf_grp = NULL;
906 }
907
908 if (p->roi_ctx) {
909 mpp_enc_roi_deinit(p->roi_ctx);
910 p->roi_ctx = NULL;
911 }
912
913 return NULL;
914 }
915