rockchip-linux / mpp

Media Process Platform (MPP) module
604 stars 172 forks source link

拿到MPP解码后的buffer的Fd,要怎么传入给RGA实现0拷贝的方式 #641

Open LeoD218 opened 4 months ago

LeoD218 commented 4 months ago

目前我已成功实现RKMPP解码+RGA硬件缩放的程序,但拿到MPP的解码数据后使用导入虚拟内存的方式传递给RGA去做缩放,速度上解码+缩放一帧4656*3496的时间大概是100ms上下浮动,然后发现将这一帧使用mpp从mjpeg数据格式转换为YUV才15ms上下, 然后拿给RGA做颜色格式的转换从YUV到RGB888竟然要80ms上下,基本耗时都在 这一步 src_handle = importbuffer_physicaladdr(bufferFd, src_buf_size); dst_handle = importbuffer_virtualaddr(dst_buf, dst_buf_size); 所以想着既然从mpp解码出来的buffer中能拿到fd,要怎么传入给RGA去实现0拷贝的方式 image

LeoD218 commented 4 months ago

RK_U32 width = 0; RK_U32 height = 0; MppBuffer buffer = NULL; // RK_U8 base = NULL; char base = NULL;

        width    = mpp_frame_get_width(frame);
        height   = mpp_frame_get_height(frame);
        buffer   = mpp_frame_get_buffer(frame);
        int bufferFd = mpp_buffer_get_fd(buffer);
        qDebug()<<"mpp_buffer_get_fd:"<<bufferFd;

        if (NULL == buffer)
        {
            return -1;
        }
        // QElapsedTimer time;
        // time.start();
        base = (char*)mpp_buffer_get_ptr(buffer);
        // qDebug()<<"resize :"<<time.elapsed();
        //RGA硬件缩放
        int src_width, src_height, src_format;
        int dst_width, dst_height, dst_format;
        int src_buf_size, dst_buf_size;
        char  *src_buf,*dst_buf;
        int src_dma_fd, dst_dma_fd;
        rga_buffer_t src = {};
        rga_buffer_t dst = {};
        rga_buffer_handle_t src_handle, dst_handle;

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

        dst_width  = 640;
        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);

        /* Allocate dma_buf, return dma_fd and virtual address. */
        ret = dma_buf_alloc(DMA_HEAP_UNCACHE_PATH, src_buf_size, &src_dma_fd, (void **)&src_buf);
        if (ret < 0) {
            printf("alloc src dma_heap buffer failed!\n");
            return -1;
        }

        ret = dma_buf_alloc(DMA_HEAP_UNCACHE_PATH, dst_buf_size, &dst_dma_fd, (void **)&dst_buf);
        if (ret < 0) {
            printf("alloc dst dma_heap buffer failed!\n");
            dma_buf_free(src_buf_size, &src_dma_fd, src_buf);
            return -1;
        }
        ret = read(bufferFd, src_buf, src_buf_size);
        //qDebug()<<"ret:"<<ret;
        if (ret < 0) {
            printf ("open file %s so memset!\n", "fault");
            return -1;
        }
        memset(dst_buf, 0x33, dst_buf_size);

        /*
 * Import the allocated dma_fd into RGA by calling
 * importbuffer_fd, and use the returned buffer_handle
 * to call RGA to process the image.
 */
        src_handle = importbuffer_fd(src_dma_fd, src_buf_size);
        dst_handle = importbuffer_fd(dst_dma_fd, dst_buf_size);
        if (src_handle == 0 || dst_handle == 0) {
            printf("import dma_fd error!\n");
            ret = -1;
            goto free_buf;
        }

        src = wrapbuffer_handle(src_handle, src_width, src_height, src_format);
        dst = wrapbuffer_handle(dst_handle, dst_width, dst_height, dst_format);

        ret = imcheck(src, dst, {}, {});
        if (IM_STATUS_NOERROR != ret) {
            // printf("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret));
            qDebug()<<"IM_STATUS_NOERROR";
            goto release_buffer;
        }
        ret = imcvtcolor(src, dst,RK_FORMAT_YCbCr_420_SP,RK_FORMAT_RGB_888);
 这个是参考rga  dma demo里面的,发现运行出错
HermanChen commented 4 months ago

DMA_HEAP_UNCACHE_PATH uncache 的 buffer 访问很慢

LeoD218 commented 4 months ago

DMA_HEAP_UNCACHE_PATH uncache 的 buffer 访问很慢

感觉我这种写法也有很多问题,我直接使用 ret = read(bufferFd, src_buf, src_buf_size);去读取Buf,然后导致程序直接闪退,找不到问题 RKMPP+RGA实现0拷贝的demo也没有可以参考的

to-vanish commented 3 months ago

老哥解决了吗