7.52. ioctl VIDIOC_REQBUFS

7.52.1. 名称

VIDIOC_REQBUFS - 启动内存映射、用户指针I/O或DMA缓冲区I/O

7.52.2. 概要

VIDIOC_REQBUFS

int ioctl(int fd, VIDIOC_REQBUFS, struct v4l2_requestbuffers *argp)

7.52.3. 参数

fd

open() 返回的文件描述符。

argp

指向结构体 v4l2_requestbuffers 的指针。

7.52.4. 描述

此ioctl用于启动 内存映射用户指针DMABUF 基于I/O。 内存映射缓冲区位于设备内存中,必须在使用此ioctl分配后才能映射到应用程序的地址空间中。 用户缓冲区由应用程序本身分配,此ioctl仅用于将驱动程序切换到用户指针I/O模式并设置一些内部结构。 同样,DMABUF缓冲区由应用程序通过设备驱动程序分配,此ioctl仅将驱动程序配置为DMABUF I/O模式,而不执行任何直接分配。

为了分配设备缓冲区,应用程序初始化结构体 v4l2_requestbuffers 结构的所有字段。 它们将 type 字段设置为相应的流或缓冲区类型,将 count 字段设置为所需的缓冲区数量,memory 必须设置为请求的I/O方法,并且 reserved 数组必须为零。 当使用指向此结构的指针调用ioctl时,驱动程序将尝试分配请求的缓冲区数量,并将实际分配的数量存储在 count 字段中。 当驱动程序耗尽可用内存时,它可能小于请求的数量,甚至为零。 当驱动程序需要更多缓冲区才能正常工作时,也可能出现更大的数字。 例如,视频输出至少需要两个缓冲区,一个显示,另一个由应用程序填充。

当不支持I/O方法时,ioctl返回 EINVAL 错误代码。

应用程序可以再次调用 ioctl VIDIOC_REQBUFS 以更改缓冲区数量。 请注意,如果任何缓冲区仍通过DMABUF映射或导出,则只有在设置了 V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS 功能时,ioctl VIDIOC_REQBUFS 才能成功。 否则,ioctl VIDIOC_REQBUFS 将返回 EBUSY 错误代码。 如果设置了 V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS,则这些缓冲区将成为孤立缓冲区,并在取消映射或关闭导出的DMABUF fd时释放。 count 值为零会释放或孤立所有缓冲区,在中止或完成任何正在进行的DMA之后,这是一个隐式的 VIDIOC_STREAMOFF

type v4l2_requestbuffers
结构体 v4l2_requestbuffers

__u32

count

请求或授予的缓冲区数量。

__u32

type

流或缓冲区的类型,这与结构体 v4l2_format type 字段相同。 有关有效值,请参见 v4l2_buf_type

__u32

memory

应用程序将此字段设置为 V4L2_MEMORY_MMAPV4L2_MEMORY_DMABUFV4L2_MEMORY_USERPTR。 请参见 v4l2_memory

__u32

capabilities

由驱动程序设置。 如果为0,则驱动程序不支持功能。 在这种情况下,您所知道的是驱动程序保证支持 V4L2_MEMORY_MMAP 并且可能支持其他 v4l2_memory 类型。 它将不支持任何其他功能。

如果您想查询具有最小副作用的功能,则可以调用此函数,将 count 设置为0,memory 设置为 V4L2_MEMORY_MMAP,并将 type 设置为缓冲区类型。 这将释放任何先前分配的缓冲区,因此这通常是在应用程序启动时完成的操作。

__u8

flags

指定其他缓冲区管理属性。 请参见 内存一致性标志

__u8

reserved[3]

保留用于将来的扩展。

V4L2 缓冲区功能标志

V4L2_BUF_CAP_SUPPORTS_MMAP

0x00000001

此缓冲区类型支持 V4L2_MEMORY_MMAP 流模式。

V4L2_BUF_CAP_SUPPORTS_USERPTR

0x00000002

此缓冲区类型支持 V4L2_MEMORY_USERPTR 流模式。

V4L2_BUF_CAP_SUPPORTS_DMABUF

0x00000004

此缓冲区类型支持 V4L2_MEMORY_DMABUF 流模式。

V4L2_BUF_CAP_SUPPORTS_REQUESTS

0x00000008

此缓冲区类型支持 请求

V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS

0x00000010

内核允许在缓冲区仍通过DMABUF映射或导出时调用 ioctl VIDIOC_REQBUFS。 这些孤立缓冲区将在取消映射或关闭导出的DMABUF fd时释放。

V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF

0x00000020

仅对无状态解码器有效。 如果设置,则用户空间可以设置 V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF 标志,以延迟返回捕获缓冲区,直到OUTPUT时间戳更改。

V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS

0x00000040

此功能由驱动程序设置,以指示队列支持缓存和内存管理提示。 但是,只有在队列用于 内存映射 流I/O时才有效。 请参见 V4L2_BUF_FLAG_NO_CACHE_INVALIDATEV4L2_BUF_FLAG_NO_CACHE_CLEANV4L2_MEMORY_FLAG_NON_COHERENT

V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS

0x00000080

如果设置,则 struct v4l2_create_buffers 中的 max_num_buffers 字段有效。 如果未设置,则最大值为 VIDEO_MAX_FRAME 缓冲区。

V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS

0x00000100

如果设置,则支持 VIDIOC_REMOVE_BUFS

内存一致性标志

V4L2_MEMORY_FLAG_NON_COHERENT

0x00000001

缓冲区是在一致性内存(它将在CPU和总线之间自动一致)或非一致性内存中分配的。 后者可以提供性能提升,例如,如果缓冲区仅由相应的设备访问,并且CPU不读取/写入该缓冲区,则可以避免CPU缓存同步/刷新操作。 但是,这需要驱动程序格外小心 - 它必须在需要一致性时通过发出缓存刷新/同步来保证内存一致性。 如果设置了此标志,V4L2将尝试在非一致性内存中分配缓冲区。 该标志仅在缓冲区用于 内存映射 I/O 并且队列报告 V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS 功能时才生效。

7.52.5. 返回值

成功时返回0,错误时返回-1,并适当设置 errno 变量。 通用错误代码在 通用错误代码 章节中描述。

EINVAL

不支持缓冲区类型(type 字段)或请求的I/O方法(memory)。