librga icon indicating copy to clipboard operation
librga copied to clipboard

RKMPP解码后buffer导出的fd该如何导入到rga中

Open LeoD218 opened this issue 1 year ago • 1 comments

我现在已经拿到MPP解码后的buffer的fd,然后使用importbuffer_virtualaddr导入mpp的buffer进行一个颜色空间转换的话没有什么问题,就是延迟太高、太慢了,所以想用importbuffer_fd的方式将MPP解码后的buffer通过fd的方式进行导入,所以我参考了rga_allocator_dma_demo.cpp这个demo去编写代码,发现导入fd也是能导入,就是进行rga颜色转换后的目标buffer获取不到,导致画面什么都不显示,以下是我编写的代码,希望能得到官方的有效回复!谢谢 ` while(1) { MppTask task = NULL;

    /* poll and wait here */
    int ret = mApi->poll(mCtx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK);
    if (ret)
    {
        qDebug("mpp output poll failed\n");
    }

    ret = mApi->dequeue(mCtx, MPP_PORT_OUTPUT, &task); /* output queue */
    if (ret)
    {
        qDebug("mpp task output dequeue failed\n");
    }
    if (task)
    {
        MppFrame frameOut = NULL;
        mpp_task_meta_get_frame(task, KEY_OUTPUT_FRAME, &frameOut);
        MppBuffer  buffer   = NULL;
        if (frameOut)
        {

            RK_U32 width    = 0;
            RK_U32 height   = 0;
            char *base = NULL;

            width    = mpp_frame_get_width(frameOut);
            height   = mpp_frame_get_height(frameOut);
            buffer   = mpp_frame_get_buffer(frameOut);
            base = (char*)mpp_buffer_get_ptr(buffer);
            int buffd = mpp_buffer_get_fd(buffer);//获取到MPP—buffer的fd

            /* 导入FD的方式 */
            int src_format;
            int dst_format;
            char *dst_buf;
            int dst_dma_fd;

            int src_buf_size, dst_buf_size;
            rga_buffer_t src_img, dst_img;
            rga_buffer_handle_t src_handle, dst_handle;

            memset(&src_img, 0, sizeof(src_img));
            memset(&dst_img, 0, sizeof(dst_img));

            int src_width = MPP_ALIGN(width,16);
            int src_height = MPP_ALIGN(height,16);
            src_format = RK_FORMAT_YCbCr_420_SP;

            int dst_width = 640;
            int dst_height = 480;
            dst_format = RK_FORMAT_RGB_888;

            src_buf_size = src_width * src_height * get_bpp_from_format(src_format);
            dst_buf_size = dst_width * dst_height * get_bpp_from_format(dst_format);

            ret = dma_buf_alloc(DMA_HEAP_PATH, dst_buf_size, &dst_dma_fd, (void **)&dst_buf);

            memset(dst_buf,0x33,dst_buf_size);
            dma_sync_cpu_to_device(dst_dma_fd);

            src_handle = importbuffer_fd(buffd, src_buf_size);
            dst_handle = importbuffer_fd(dst_dma_fd, dst_buf_size);
            qDebug()<<"src_mpp_fd:"<<buffd;         //输出:src_mpp_fd:18
            qDebug()<<"dst_dma_fd:"<<dst_dma_fd;    //输出:dst_dma_fd:27

            if (src_handle == 0 || dst_handle == 0) {
                printf("importbuffer failed!\n");
                qDebug()<<"importbuffer failed!";
                goto free_buf;
            }

            src_img = wrapbuffer_handle(src_handle, src_width, src_height, src_format);
            dst_img = wrapbuffer_handle(dst_handle, dst_width, dst_height, dst_format);

            ret = imcheck(src_img, dst_img, {}, {});
            if (IM_STATUS_NOERROR != ret) {
                printf("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret));
                return;
            }
            ret = imcvtcolor(src_img, dst_img,RK_FORMAT_YCbCr_420_SP,RK_FORMAT_RGB_888);
            dma_sync_device_to_cpu(dst_dma_fd);
            if (ret == IM_STATUS_SUCCESS) {

                QImage img1((unsigned char *)dst_buf,dst_width,dst_height,QImage::Format_RGB888);
                if (callback != nullptr) {
                    callback(img1);
                }
            }
            else
            {
                printf("rga resize failed");
                goto release_buffer;
            }
        release_buffer:
            if (src_handle)
                releasebuffer_handle(src_handle);
            if (dst_handle)
                releasebuffer_handle(dst_handle);
        free_buf:
            dma_buf_free(dst_buf_size, &dst_dma_fd, dst_buf);

            ret = mApi->enqueue(mCtx, MPP_PORT_OUTPUT, task);
            if (mpp_frame_get_eos(frameOut))
            {
                printf("found eos frame\n");
                continue;
            }
            if (ret)
            {
                printf("mpp task output enqueue failed\n");
                continue;
            }
        }
        else
        {
            qDebug()<<"Error unFished decode;";
        }
    }
}
`

官方如需其它信息,我会尽快补充

LeoD218 avatar Oct 30 '24 04:10 LeoD218

问题已经解决了么?可以尝试控制变量替换源、目标为虚拟地址、dma_buf fd试试

Cerf-Yu avatar Jan 21 '25 08:01 Cerf-Yu