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

指向 struct v4l2_requestbuffers 的指针。

7.52.4. 描述

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

要分配设备缓冲区,应用程序需要初始化 struct 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
struct v4l2_requestbuffers

__u32

count

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

__u32

type

流或缓冲区的类型,这与 struct 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_MMAPtype 设置为缓冲区类型的情况下调用此函数。这将释放之前分配的任何缓冲区,因此这通常是在应用程序启动时完成的操作。

__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)。