关于mpp解码mjpeg的部分问题
参考(见https://github.com/rockchip-linux/mpp/issues/592 )给出了如下的demo int init_mjpeg_decoder(MpiDecLoopData data) { MPP_RET ret = MPP_OK; MppCtx ctx = NULL; MppApi *mpi = NULL; MppPacket packet = NULL; MppFrame frame = NULL; MppBuffer frm_buf = NULL; RK_U32 need_split = 1;
ret = dec_buf_mgr_init(&(data.buf_mgr));
if (ret) {
mpp_err("dec_buf_mgr_init failed\n");
return -1;
}
ret = mpp_frame_init(&frame); /* output frame */
if (ret) {
printf("mpp_frame_init failed\n");
}
RK_U32 hor_stride = MPP_ALIGN(1280, 16);
RK_U32 ver_stride = MPP_ALIGN(720, 16);
data.frm_grp = dec_buf_mgr_setup(data.buf_mgr, hor_stride * ver_stride * 4, 4, MPP_DEC_BUF_HALF_INT);
if (!(data.frm_grp))
{
printf("failed to get buffer group for input frame ret %d\n", ret);
ret = MPP_NOK;
}
ret = mpp_buffer_get(data.frm_grp, &frm_buf, hor_stride * ver_stride * 4);
if (ret) {
printf("failed to get buffer for input frame ret %d\n", ret);
return -1;
}
mpp_frame_set_buffer(frame, frm_buf);
// 创建解码上下文
ret = mpp_create(&ctx, &mpi);
if (ret) {
printf("Failed to create MPP context\n");
return -1;
}
// 初始化解码器为 JPEG 模式s
ret = mpp_init(ctx, MPP_CTX_DEC, MPP_VIDEO_CodingMJPEG);
if (ret) {
printf("Failed to initialize MPP decoder\n");
mpp_destroy(ctx);
return -1;
}
MppDecCfg cfg = NULL;
mpp_dec_cfg_init(&cfg);
ret = mpi->control(ctx, MPP_DEC_GET_CFG, cfg);
if (ret != MPP_OK)
{
printf("%p failed to get decoder cfg ret %d ", ctx, ret);
return -1;
}
MppFrameFormat dstFormat = MPP_FMT_RGB565;
ret = mpi->control(ctx, MPP_DEC_SET_OUTPUT_FORMAT, &(dstFormat));
if (ret != MPP_OK)
{
printf("Failed to set output format 0x%x\n", dstFormat);
return -1;
}
// ret = mpi->control(ctx, MPP_DEC_SET_IMMEDIATE_OUT , need_split);
// if (MPP_OK != ret) {
// printf("Failed to set MPP_DEC_MODE\n");
// return -1;
// }
ret = mpp_dec_cfg_set_u32(cfg, "base:split_parse", need_split);
if (ret) {
mpp_err("%p failed to set split_parse ret %d\n", ctx, ret);
return -1;
}
// 使配置生效
ret = mpi->control(ctx, MPP_DEC_SET_CFG, cfg);
if (ret != MPP_OK)
{
printf("%p failed to set cfg %p ret %d ", ctx, cfg, ret);
mpp_dec_cfg_deinit(cfg);
return -1;
}
// 释放配置内存
mpp_dec_cfg_deinit(cfg);
data.ctx = ctx;
data.mpi = mpi;
data.packet = packet;
data.frame = frame;
puts("init_mjpeg_decoder success\n");
return 0;
}
// 解码一帧 MJPEG 图像 int decode_mjpeg_frame(MpiDecLoopData *data, uint8_t *mjpeg_data, size_t mjpeg_size) { MPP_RET ret = MPP_OK; MppCtx ctx = data->ctx; MppApi *mpi = data->mpi; MppPacket packet = NULL; MppFrame frame = data->frame; MppTask task = NULL;
if (data->pkt_grp == NULL) {
ret = mpp_buffer_group_get_internal(&(data->pkt_grp), MPP_BUFFER_TYPE_ION);
if (ret) {
mpp_err("memGroup mpp_buffer_group_get failed %d\n", ret);
return ret;
}
}
// if (!(data->pkt_grp))
// {
// printf("failed to get buffer group for input frame ret %d\n", ret);
// ret = MPP_NOK;
// }
puts("test1\n"); // 创建解码包 MppBuffer input_buf = NULL; printf("mjpeg_size:%d\n",mjpeg_size); ret = mpp_buffer_get(data->pkt_grp, &input_buf, mjpeg_size); puts("test1-1\n"); if (ret != MPP_OK) { printf("allocate input picture buffer failed code:%d\n",ret); return -1; } puts("test1-2\n"); memcpy((RK_U8 *)mpp_buffer_get_ptr(input_buf), mjpeg_data, mjpeg_size); ret = mpp_packet_init_with_buffer(&packet, input_buf);
puts("test2\n");
ret = mpi->poll(ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
puts("test2-1\n");
if (ret) {
mpp_err("%p mpp input poll failed\n", ctx);
return ret;
}
puts("test3\n"); ret = mpi->dequeue(ctx, MPP_PORT_INPUT, &task); /* input queue */ if (ret) { printf("%p mpp task input dequeue failed\n", ctx); return ret; }
mpp_task_meta_set_packet(task, KEY_INPUT_PACKET, packet);
mpp_task_meta_set_frame (task, KEY_OUTPUT_FRAME, frame);
puts("test4\n"); ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task); /* input queue */ if (ret) { mpp_err("%p mpp task input enqueue failed\n", ctx); return ret; }
/* poll and wait here */
ret = mpi->poll(ctx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK);
if (ret) {
mpp_err("%p mpp output poll failed\n", ctx);
return ret;
}
ret = mpi->dequeue(ctx, MPP_PORT_OUTPUT, &task); /* output queue */
if (ret) {
mpp_err("%p mpp task output dequeue failed\n", ctx);
return ret;
}
if (task) {
MppFrame frame_out = NULL;
mpp_task_meta_get_frame(task, KEY_OUTPUT_FRAME, &frame_out);
if (frame)
{
puts("decoded success!");
}
else
{
puts("decoded failed");
}
}
ret = mpi->dequeue(ctx, MPP_PORT_INPUT, &task); /* input queue */
if (ret) {
mpp_err("%p mpp task input dequeue failed\n", ctx);
return ret;
}
if (task) {
MppPacket packet_out = NULL;
mpp_task_meta_get_packet(task, KEY_INPUT_PACKET, &packet_out);
if (!packet_out || packet_out != packet)
mpp_err_f("mismatch packet %p -> %p\n", packet, packet_out);
mpp_packet_deinit(&packet_out);
/* input empty task back to mpp to maintain task status */
ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task);
if (ret)
mpp_err("%p mpp task input enqueue failed\n", ctx);
}
return 0;
}
但是当程序执行到 puts("test2\n"); ret = mpi->poll(ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK); puts("test2-1\n"); 给出了段错误,无法解决问题