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_PARMVIDIOC_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() 函数。