mpp icon indicating copy to clipboard operation
mpp copied to clipboard

关于mpp解码mjpeg的部分问题

Open pan1024 opened this issue 1 year ago • 0 comments

参考(见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"); 给出了段错误,无法解决问题

pan1024 avatar Sep 20 '24 06:09 pan1024