Toybrick

RK3588 HDMI 采集问题

MadDog

中级会员

积分
377
发表于 2022-12-16 11:59:45    查看: 1224|回复: 12 | [复制链接]    打印 | 显示全部楼层
大家好:
我使用的的是rootfs系统,实现HDMI采集,我希望使用的的是dma的模式;在对V4l2设备进行设置的时候,希望采用的是dma方式,在进行VIDIOC_QBUF的时候,系统报错:


调用VIDIOC_QBUF的时候,传进去的是一个单独申请的dma的fd

按照我的理解,进行dma映射的时候,应该是走iommu的模式,结果走到了swiotlb的模式了,
请问有办法设置现在的hdmirx驱动使用iommu模式吗?如果有,如何进行设置?



回复

使用道具 举报

jefferyzhang

论坛元老

积分
11473
发表于 2022-12-16 12:23:49 | 显示全部楼层
支持DMA buffer
回复

使用道具 举报

MadDog

中级会员

积分
377
 楼主| 发表于 2022-12-16 13:43:15 | 显示全部楼层

错误如图

本帖最后由 MadDog 于 2022-12-16 13:44 编辑

C:\Users\zyy\Desktop\37c326b4b56becf7b8ffc005612da85.png

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

MadDog

中级会员

积分
377
 楼主| 发表于 2022-12-16 14:02:47 | 显示全部楼层

struct v4l2_format fmt_info;

fmt_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
fmt_info.fmt .pix_mp .width = 3840;
fmt info.fmt .pix _mp .height = 2160;
fmt_info.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_BGR24;
fmt_info.fmtpix_mp.field = V4L2_FIELD_NONE;
fmt_info.fmt.pix_mp .num_planes = 1;
int err;
err = ioctl(device_fd, VIDIOC_S_FMT, &fmt_info);


这是设定采集格式的代码,没有出错。然后是图中设定采用DMABUF方式,在VIDIOC_QBUFF
的时候报错


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

jefferyzhang

论坛元老

积分
11473
发表于 2022-12-17 10:46:41 | 显示全部楼层

1. buffer count最小要为4
2. buffer format要先check是不是支持的,目前除了BGR,还有可能是NV12等其他格式
3. 外部分配的buffer size要16对齐
4. 外部分配的buffer你得先sfmt完,全部q进去,再steam on,然后再开始dq
回复

使用道具 举报

MadDog

中级会员

积分
377
 楼主| 发表于 2022-12-19 10:05:16 | 显示全部楼层
jefferyzhang 发表于 2022-12-17 10:46
1. buffer count最小要为4
2. buffer format要先check是不是支持的,目前除了BGR,还有可能是NV12等其他格 ...

“外部分配的buffer你得先sfmt完”,sfmt完事什么意思?没理解,请帮忙详细解释一下,谢谢。
回复

使用道具 举报

MadDog

中级会员

积分
377
 楼主| 发表于 2022-12-19 10:56:55 | 显示全部楼层
jefferyzhang 发表于 2022-12-17 10:46
1. buffer count最小要为4
2. buffer format要先check是不是支持的,目前除了BGR,还有可能是NV12等其他格 ...

1:原来我设定的buffer count 是3,针对你的建议,修改为 5 了
2:设置BGR3,设定后再次从设备获取,也是BGR3,所以应该没有问题;
3:分配的dma buf,大小是3840*2160*3,肯定是16对齐的;
4:“”外部分配的buffer你得先sfmt完”, 没理解,所以未做修改

代码依然在VIDIOC_QBUF发生错,返回ioctl函数返回 -1, dmesg看系统日志,
同步的错误输出是:
[ 4697.116017] Error getting dmabuf scatterlist
[ 4748.893811] rk_hdmirx fdee0000.hdmirx-controller: swiotlb buffer is full (sz: 524288 bytes), total 32768 (slots), used 3907 (slots)
[ 4748.894890] Error getting dmabuf scatterlist
[ 4748.895272] videobuf2_common: [cap-00000000b6ef9f97] __prepare_dmabuf: failed to map dmabuf for plane 0
[ 4748.896158] videobuf2_common: [cap-00000000b6ef9f97] __buf_prepare: buffer preparation failed: -22
回复

使用道具 举报

MadDog

中级会员

积分
377
 楼主| 发表于 2022-12-19 11:11:52 | 显示全部楼层
jefferyzhang 发表于 2022-12-17 10:46
1. buffer count最小要为4
2. buffer format要先check是不是支持的,目前除了BGR,还有可能是NV12等其他格 ...

分配dma buf 的方式:
struct drm_mode_create_dumb create = {};
        struct drm_mode_map_dumb map = {};
        struct drm_mode_destroy_dumb destroy = {};       
       
        memset(&create, 0, sizeof(drm_mode_create_dumb));
        create.width = (size + align - 1) & (~(align - 1));
        create.height = 1;
        create.bpp = 8;
//        create.flags = flags;
       
        int ret = drmIoctl(device_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
        if (ret < 0)
        {
                fprintf(stderr, "can not create dumb buffer (%d): %m \n", errno);
                return -errno;               
        }
       
        struct drm_prime_handle prime_handle;
        memset(&prime_handle, 0, sizeof(struct drm_prime_handle));
        prime_handle.handle = create.handle;
        prime_handle.fd = -1;
        prime_handle.flags = DRM_CLOEXEC | DRM_RDWR;
        ret = drmIoctl(device_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime_handle);       
        if (ret != 0)
        {
                fprintf(stderr, "can not create frame buffer (%d) : %m \n", errno);
                ret = -errno;
               
                memset(&destroy, 0, sizeof(drm_mode_destroy_dumb));
                destroy.handle = create.handle;
                drmIoctl(device_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
               
                return ret;
        }

其中设备打开的是:
device_fd = open("/dev/video0", O_RDWR | O_CLOEXEC);
回复

使用道具 举报

jefferyzhang

论坛元老

积分
11473
发表于 2022-12-19 13:05:23 | 显示全部楼层
MadDog 发表于 2022-12-19 10:05
“外部分配的buffer你得先sfmt完”,sfmt完事什么意思?没理解,请帮忙详细解释一下,谢谢。 ...

set format
回复

使用道具 举报

jefferyzhang

论坛元老

积分
11473
发表于 2022-12-19 13:06:20 | 显示全部楼层
MadDog 发表于 2022-12-19 11:11
分配dma buf 的方式:
struct drm_mode_create_dumb create = {};
        struct drm_mode_map_dumb map = {};

你板子hdmiin有能用过么?是toybrick的板子么?我建议你先确认hdmiin是正常的,并且kernel和驱动是正确的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表