-
Notifications
You must be signed in to change notification settings - Fork 247
Open
Description
我有一个USB摄像头,支持YUYV422 + MJPEG 格式,需要做一个rtsp服务,目前YUYV422 格式已经通了,因为分辨率比较低,需要支持MJPEG输入。
现在碰到的问题是:
- 打开摄像头,获取MJPEG 输出,OK
- 调用MJPEG 解码,卡主。 我看了一些帖子,MJPEG解码需要参照dec_advance 来做,但是还是在poll 等待解码器输出时卡主。
测试代码如下:
MPP_RET decode_one_jpeg(const char * path) {
MPP_RET ret;
MppApi *mpi;
MppCtx ctx;
MppTask task = NULL;
MppDecCfg cfg = NULL;
RK_U32 need_split = 1;
MppFrameFormat jpgOutputFmt = MPP_FMT_YUV420SP;
MppPacket packet;
MppFrame frame;
FILE *fp = NULL;
char *jpg_buf = NULL;
int n;
MppBufferGroup buf_grp;
MppBuffer frm_buf;
// read buffer
jpg_buf = malloc(1024*1024);
if (NULL == jpg_buf) {
printf("failed to allocate\n");
ret = MPP_ERR_NULL_PTR;
goto EXIT;
}
fp = fopen(path, "r");
if (NULL == fp) {
printf("open input error\n");
ret = MPP_ERR_OPEN_FILE;
goto EXIT;
}
n = fread(jpg_buf, 1, 1024*1024, fp);
if (n <= 0) {
printf("fread error\n");
ret = MPP_ERR_OPEN_FILE;
goto EXIT;
}
mpp_packet_init(&packet, jpg_buf, n);
// allocate buffer for frame
ret = mpp_buffer_group_get_internal(&buf_grp, MPP_BUFFER_TYPE_DRM | MPP_BUFFER_FLAGS_CACHABLE);
if (ret) {
printf("failed to get mpp buffer group ret %d\n", ret);
goto EXIT;
}
ret = mpp_buffer_get(buf_grp, &frm_buf, 640 * 480 * 4);
if (ret) {
printf("failed to get buffer for input frame ret %d\n", ret);
goto EXIT;
}
mpp_frame_init(&frame);
mpp_frame_set_buffer(frame, frm_buf);
// init decoder
ret = mpp_create(&ctx, &mpi);
if (ret) {
printf("mpp_create error: %d\n", ret);
goto EXIT;
}
ret = mpp_init(ctx, MPP_CTX_DEC, MPP_VIDEO_CodingMJPEG);
if (ret) {
printf("mpp_init error: %d\n", ret);
goto EXIT;
}
mpp_dec_cfg_init(&cfg);
ret = mpi->control(ctx, MPP_DEC_GET_CFG, cfg);
if (ret) {
printf("control error: %d\n", ret);
goto EXIT;
}
ret = mpp_dec_cfg_set_u32(cfg, "base:split_parse", need_split);
if (ret) {
printf("mpp_dec_cfg_set_u32 ret: %d", ret);
goto EXIT;
}
ret = mpi->control(ctx, MPP_DEC_SET_CFG, cfg);
if (ret) {
printf("failed to set decoder cfg ret: %d", ret);
goto EXIT;
}
ret = mpi->control(ctx, MPP_DEC_SET_OUTPUT_FORMAT, &jpgOutputFmt);
if (ret) {
printf("failed to set output fromat ret: %d", ret);
goto EXIT;
}
printf("start poll input\n");
ret = mpi->poll(ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
if (ret) {
printf("input poll error: %d", ret);
goto EXIT;
}
printf("finish poll input\n");
ret = mpi->dequeue(ctx, MPP_PORT_INPUT, &task);
if (ret) {
printf("dequeue input error: %d", ret);
goto EXIT;
}
printf("finish dequeue input\n");
mpp_assert(task);
mpp_task_meta_set_packet(task, KEY_INPUT_PACKET, packet);
mpp_task_meta_set_packet(task, KEY_OUTPUT_FRAME, frame);
ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task);
if (ret) {
printf("enqueue input error: %d", ret);
goto EXIT;
}
printf("finish enqueue input\n");
// 此处卡主
ret = mpi->poll(ctx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK);
if (ret) {
printf("output poll error: %d", ret);
goto EXIT;
}
printf("finish poll output\n");
ret = mpi->dequeue(ctx, MPP_PORT_OUTPUT, &task);
if (ret) {
printf("dequeue output error: %d", ret);
goto EXIT;
}
EXIT:
if (fp) {
fclose(fp);
}
if (jpg_buf) {
free(jpg_buf);
}
if (frm_buf) {
mpp_buffer_put(frm_buf);
}
if (buf_grp) {
mpp_buffer_group_put(buf_grp);
}
mpp_packet_deinit(&packet);
return ret;
}
执行时输出,然后卡住
start poll input
finish poll input
finish dequeue input
finish enqueue input
设备为 rk3568 + debian 11
Metadata
Metadata
Assignees
Labels
No labels