7.71. V4L2 read()¶
7.71.1. 名称¶
v4l2-read - 从 V4L2 设备读取
7.71.2. 概要¶
#include <unistd.h>
-
ssize_t read(int fd, void *buf, size_t count)¶
7.71.3. 参数¶
fd
由
open()
返回的文件描述符。buf
要填充的缓冲区
count
要读取的最大字节数
7.71.4. 描述¶
read()
尝试从文件描述符 fd
读取最多 count
个字节到从 buf
开始的缓冲区中。缓冲区中数据的布局在各自的设备接口部分讨论,请参阅 ##。如果 count
为零,read()
返回零,并且没有其他结果。如果 count
大于 SSIZE_MAX
,则结果未指定。无论 count
的值如何,每次 read()
调用最多提供一个帧(两个场)的数据。
默认情况下,read()
阻塞,直到数据可用。当 O_NONBLOCK
标志被传递给 open()
函数时,如果没有数据可用,它会立即返回并显示 EAGAIN
错误代码。select()
或 poll()
函数始终可用于暂停执行,直到数据可用。所有支持 read()
函数的驱动程序还必须支持 select()
和 poll()
。
驱动程序可以使用单个或多个缓冲区,并在内部缓冲区被填满后丢弃最旧或最新的帧,以不同的方式实现读取功能。
read()
永远不会返回正在填充的缓冲区的“快照”。使用单个缓冲区时,驱动程序将在应用程序开始读取缓冲区时停止捕获,直到读取完成。因此,只有垂直消隐间隔的时间可用于读取,或者捕获速率必须低于视频标准的标称帧速率。
在活动图像期间或分隔顶部和底部场的垂直消隐期间调用 read()
时的行为取决于丢弃策略。丢弃最旧帧的驱动程序会继续捕获到内部缓冲区中,不断覆盖之前未读取的帧,并在 read()
调用时尽快返回正在接收的帧。
丢弃最新帧的驱动程序会停止捕获,直到下次 read()
调用。在 read()
时接收到的帧被丢弃,而是返回后续帧。同样,这意味着捕获速率会降低到标称帧速率的一半或更低。此模型的一个示例是 bttv 驱动程序的视频读取模式,当调用 read()
并返回 DMA 完成时,它会启动到用户内存的 DMA。
在多缓冲区模型中,驱动程序维护一个内部缓冲区环,自动前进到下一个空闲缓冲区。当应用程序能够足够快地清空缓冲区时,这允许连续捕获。同样,当驱动程序耗尽空闲缓冲区时,行为取决于丢弃策略。
应用程序可以使用 VIDIOC_G_PARM 和 VIDIOC_S_PARM ioctl 获取和设置驱动程序内部使用的缓冲区数量。但是,它们是可选的。不会报告并且无法更改丢弃策略。有关最低要求,请参阅 接口。
7.71.5. 返回值¶
成功时,将返回读取的字节数。如果此数字小于请求的字节数,或一个帧所需的数据量,则它不是错误。例如,这可能发生,因为 read()
被信号中断。发生错误时,将返回 -1,并相应地设置 errno
变量。在这种情况下,下一次读取将从新帧的开头开始。可能的错误代码是
- EAGAIN
已使用 O_NONBLOCK 选择非阻塞 I/O,并且没有立即可用于读取的数据。
- EBADF
fd
不是有效的文件描述符或未打开以进行读取,或者该进程已打开最大文件数。- EBUSY
驱动程序不支持多个读取流,并且该设备已在使用中。
- EFAULT
buf
引用无法访问的内存区域。- EINTR
在读取任何数据之前,调用被信号中断。
- EIO
I/O 错误。这表明某些硬件问题或与远程设备(USB 摄像头等)通信失败。
- EINVAL
此驱动程序、此设备或通常在此类型设备上不支持
read()
函数。