Skip to content

MPP JPEG解码卡住 #898

@tubzby

Description

@tubzby

我有一个USB摄像头,支持YUYV422 + MJPEG 格式,需要做一个rtsp服务,目前YUYV422 格式已经通了,因为分辨率比较低,需要支持MJPEG输入。

现在碰到的问题是:

  1. 打开摄像头,获取MJPEG 输出,OK
  2. 调用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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions