Toybrick

标题: RK3588 HDMI 采集问题 [打印本页]

作者: MadDog    时间: 2022-12-16 11:59
标题: RK3588 HDMI 采集问题
大家好:
我使用的的是rootfs系统,实现HDMI采集,我希望使用的的是dma的模式;在对V4l2设备进行设置的时候,希望采用的是dma方式,在进行VIDIOC_QBUF的时候,系统报错:


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

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




作者: jefferyzhang    时间: 2022-12-16 12:23
支持DMA buffer
作者: MadDog    时间: 2022-12-16 13:43
标题: 错误如图
本帖最后由 MadDog 于 2022-12-16 13:44 编辑

C:\Users\zyy\Desktop\37c326b4b56becf7b8ffc005612da85.png
作者: MadDog    时间: 2022-12-16 14:02
jefferyzhang 发表于 2022-12-16 12:23
支持DMA buffer

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
的时候报错



作者: jefferyzhang    时间: 2022-12-17 10:46

1. buffer count最小要为4
2. buffer format要先check是不是支持的,目前除了BGR,还有可能是NV12等其他格式
3. 外部分配的buffer size要16对齐
4. 外部分配的buffer你得先sfmt完,全部q进去,再steam on,然后再开始dq
作者: MadDog    时间: 2022-12-19 10:05
jefferyzhang 发表于 2022-12-17 10:46
1. buffer count最小要为4
2. buffer format要先check是不是支持的,目前除了BGR,还有可能是NV12等其他格 ...

“外部分配的buffer你得先sfmt完”,sfmt完事什么意思?没理解,请帮忙详细解释一下,谢谢。
作者: MadDog    时间: 2022-12-19 10:56
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    时间: 2022-12-19 11:11
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    时间: 2022-12-19 13:05
MadDog 发表于 2022-12-19 10:05
“外部分配的buffer你得先sfmt完”,sfmt完事什么意思?没理解,请帮忙详细解释一下,谢谢。 ...

set format
作者: jefferyzhang    时间: 2022-12-19 13:06
MadDog 发表于 2022-12-19 11:11
分配dma buf 的方式:
struct drm_mode_create_dumb create = {};
        struct drm_mode_map_dumb map = {};

你板子hdmiin有能用过么?是toybrick的板子么?我建议你先确认hdmiin是正常的,并且kernel和驱动是正确的
作者: MadDog    时间: 2022-12-19 13:45
jefferyzhang 发表于 2022-12-19 13:06
你板子hdmiin有能用过么?是toybrick的板子么?我建议你先确认hdmiin是正常的,并且kernel和驱动是正确的 ...

能用,通过Qt V4L2 test Utility能够打开HDMI IN, 看见图像,但是帧率很低

系统启动的时候:

root@RK3588:/# dmesg | grep "hdmirx"
[    2.497774] rk_hdmirx fdee0000.hdmirx-controller: No reserved memory for HDMIRX, use default CMA
[    2.498575] rk_hdmirx fdee0000.hdmirx-controller: hdmirx_probe: cpu_aff:0x400, Bound_cpu:4, wdt_cfg_bound_cpu:5
[    2.499950] rk_hdmirx fdee0000.hdmirx-controller: hdmirx_audio_interrupts_setup: 0
[    2.501594] rk_hdmirx fdee0000.hdmirx-controller: rk_hdmirx_hdcp_register success
[    2.502299] rk_hdmirx fdee0000.hdmirx-controller: fdee0000.hdmirx-controller driver probe ok!
[    3.250301] rockchip-dmc dmc: hdmirx_rate = 2112000000
[    4.753210] rk_hdmirx fdee0000.hdmirx-controller: hdmirx_audio_interrupts_setup: 1
[    5.148154] fdee0000.hdmirx-controller: hdmirx_wait_lock_and_get_timing signal lock ok, i:51!
[    5.214575] fdee0000.hdmirx-controller: Vertical Sync threshold reached interrupt 0x2
[    5.429120] fdee0000.hdmirx-controller: hdmirx_format_change: New format: 3840x2160p30.00 (4400x2250)
[    5.735924] rk_hdmirx fdee0000.hdmirx-controller: hdmirx_delayed_work_audio: enable audio
[    5.736646] rk_hdmirx fdee0000.hdmirx-controller: hdmirx_delayed_work_audio: restart audio fs(44100 -> 48000) ch(0 -> 1)
[    5.737612] rk_hdmirx fdee0000.hdmirx-controller: hdmirx_audio_fifo_init
[    5.939257] rk_hdmirx fdee0000.hdmirx-controller: audio on
root@RK3588:/# dmesg | grep "CMA"
[    0.806170] Reserved memory: created CMA memory pool at 0x0000000010000000, size 512 MiB
[    2.497774] rk_hdmirx fdee0000.hdmirx-controller: No reserved memory for HDMIRX, use default CMA
root@RK3588:/#
作者: jefferyzhang    时间: 2022-12-19 16:51
对了,还有你DMA的buffer必须是CMA的
作者: qianyun    时间: 2023-3-15 16:31
请问有解决么,我这边用rk3588 hdmirx进行dma方式取数据也出现了一样的错误~但是采用mmap方式写成文件是能够取到视频数据(1080P)的
作者: MadDog    时间: 2023-3-27 16:48
qianyun 发表于 2023-3-15 16:31
请问有解决么,我这边用rk3588 hdmirx进行dma方式取数据也出现了一样的错误~但是采用mmap方式写成文件是能 ...

解决了,关键是分配dma内存的时候,必须是CMA的

作者: qianyun    时间: 2023-3-29 20:34
MadDog 发表于 2023-3-27 16:48
解决了,关键是分配dma内存的时候,必须是CMA的

请问一下分配dma内存是申请drm内存时候来指定CMA的吗,也就是应用层修改的意思?
作者: qianyun    时间: 2023-3-29 20:35
MadDog 发表于 2023-3-27 16:48
解决了,关键是分配dma内存的时候,必须是CMA的

还是说需要修改驱动代码




欢迎光临 Toybrick (https://t.rock-chips.com/) Powered by Discuz! X3.3