2.4. 视频设备的内部表示¶
/dev
目录中的实际设备节点是使用 video_device
结构体 (v4l2-dev.h
) 创建的。此结构体可以动态分配或嵌入到更大的结构体中。
要动态分配它,请使用 video_device_alloc()
struct video_device *vdev = video_device_alloc();
if (vdev == NULL)
return -ENOMEM;
vdev->release = video_device_release;
如果将其嵌入到更大的结构体中,则必须将 release()
回调设置为您自己的函数
struct video_device *vdev = &my_vdev->vdev;
vdev->release = my_vdev_release;
必须设置 release()
回调,并且当视频设备的最后一个用户退出时会调用它。
默认的 video_device_release()
回调目前只是调用 kfree
来释放已分配的内存。
还有一个 video_device_release_empty()
函数,它不执行任何操作(为空),如果该结构体是嵌入式的,并且在释放时无需执行任何操作,则应使用该函数。
您还应该设置 video_device
的以下字段
video_device
->v4l2_dev:必须设置为v4l2_device
父设备。video_device
->name:设置为具有描述性且唯一的内容。video_device
->vfl_dir:对于捕获设备,请将其设置为VFL_DIR_RX
(VFL_DIR_RX
的值为 0,因此通常已经是默认值),对于输出设备,请设置为VFL_DIR_TX
,对于 mem2mem(编解码器)设备,请设置为VFL_DIR_M2M
。video_device
->fops:设置为v4l2_file_operations
结构体。video_device
->ioctl_ops:如果您使用v4l2_ioctl_ops
来简化 ioctl 维护(强烈建议使用此方法,并且将来可能会强制使用!),则将其设置为您的v4l2_ioctl_ops
结构体。video_device
->vfl_type 和video_device
->vfl_dir 字段用于禁用不匹配类型/dir 组合的操作。例如,VBI 操作对非 VBI 节点禁用,输出操作对捕获设备禁用。这使得为 vbi 和视频节点提供一个v4l2_ioctl_ops
结构体成为可能。video_device
->lock:如果您想在驱动程序中执行所有锁定,则将其保留为NULL
。否则,您可以提供指向mutex_lock
结构体的指针,并且在调用video_device
->unlocked_ioctl 文件操作之前,核心会获取此锁并在之后释放。有关更多详细信息,请参见下一节。video_device
->queue:指向与此设备节点关联的struct vb2_queue
的指针。如果 queue 不是NULL
,并且 queue->lock 不是NULL
,则 queue->lock 用于排队 ioctl(VIDIOC_REQBUFS
、CREATE_BUFS
、QBUF
、DQBUF
、QUERYBUF
、PREPARE_BUF
、STREAMON
和STREAMOFF
),而不是上面的锁。这样,vb2 排队框架不必等待其他 ioctl。此队列指针还被 vb2 辅助函数用于检查排队所有权(即,是否允许调用它的文件句柄执行该操作)。video_device
->prio:跟踪优先级。用于实现VIDIOC_G_PRIORITY
和VIDIOC_S_PRIORITY
。如果将其保留为NULL
,则它将使用struct v4l2_prio_state
中的v4l2_device
。如果您想为每个(组)设备节点拥有单独的优先级状态,则可以将其指向您自己的v4l2_prio_state
结构体。video_device
->dev_parent:仅当 v4l2_device 注册时使用NULL
作为父device
结构体时才设置此项。这种情况仅发生在单个硬件设备具有多个 PCI 设备,它们都共享相同的v4l2_device
核心时。cx88 驱动程序是这种情况的一个示例:一个核心
v4l2_device
结构体,但它被原始视频 PCI 设备 (cx8800) 和 MPEG PCI 设备 (cx8802) 使用。由于v4l2_device
不能同时与两个 PCI 设备关联,因此在没有父设备的情况下进行设置。但是,当初始化struct video_device
时,您确实知道要使用哪个父 PCI 设备,因此您可以将dev_device
设置为正确的 PCI 设备。
如果您使用 v4l2_ioctl_ops
,则应将 video_device
->unlocked_ioctl 设置为 video_ioctl2()
在您的 v4l2_file_operations
结构体中。
在某些情况下,您希望告诉核心您在 v4l2_ioctl_ops
中指定的函数应被忽略。您可以通过在调用 video_register_device()
之前调用此函数来标记此类 ioctl
v4l2_disable_ioctl
(vdev
, cmd)。
如果根据外部因素(例如,正在使用的卡)您想关闭 v4l2_ioctl_ops
中的某些功能,而无需创建新的结构体,则通常需要这样做。
v4l2_file_operations
结构体是 file_operations 的子集。主要区别在于 inode 参数被省略,因为它从未使用过。
如果需要与媒体框架集成,则必须通过调用 media_entity_pads_init()
初始化嵌入在 video_device
结构体(实体字段)中的 media_entity
结构体
struct media_pad *pad = &my_vdev->pad;
int err;
err = media_entity_pads_init(&vdev->entity, 1, pad);
之前必须已初始化 pads 数组。无需手动设置 struct media_entity
类型和名称字段。
当视频设备打开/关闭时,将自动获取/释放对该实体的引用。
2.4.1. ioctls 和锁定¶
V4L 核心提供可选的锁定服务。主要服务是 struct video_device
中的 lock 字段,它是指向互斥量的指针。如果您设置此指针,则 unlocked_ioctl 将使用它来序列化所有 ioctl。
如果您正在使用 videobuf2 框架,则可以设置第二个锁:video_device
->queue->lock。如果设置,则此锁将用于代替 video_device
->lock 来序列化所有排队 ioctl(有关这些 ioctl 的完整列表,请参见上一节)。
为排队 ioctl 使用不同锁的优点是,对于某些驱动程序(尤其是 USB 驱动程序),某些命令(例如设置控件)可能需要很长时间,因此您想为缓冲区排队 ioctl 使用单独的锁。这样,您的 VIDIOC_DQBUF
不会因为驱动程序忙于更改例如网络摄像头的曝光而停顿。
当然,您始终可以通过将两个锁指针都保留为 NULL
来自己完成所有锁定。
对于 videobuf2,如果适用,您将需要实现 wait_prepare()
和 wait_finish()
回调来解锁/锁定。如果您使用 queue->lock
指针,则可以使用辅助函数 vb2_ops_wait_prepare()
和 vb2_ops_wait_finish()
。
热插拔断开的实现也应在调用 v4l2_device_disconnect 之前从 video_device
获取锁。如果您还使用 video_device
->queue->lock,则必须首先锁定 video_device
->queue->lock,然后锁定 video_device
->lock。这样,您可以确保在调用 v4l2_device_disconnect()
时没有 ioctl 正在运行。
2.4.2. 视频设备注册¶
接下来,使用 video_register_device()
注册视频设备。这将为您创建字符设备。
err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
if (err) {
video_device_release(vdev); /* or kfree(my_vdev); */
return err;
}
如果 v4l2_device
父设备具有非 NULL
mdev 字段,则视频设备实体将自动在媒体设备中注册。
注册哪个设备取决于类型参数。存在以下类型
设备名称 |
用法 |
|
---|---|---|
|
|
用于视频输入/输出设备 |
|
|
用于垂直消隐数据(即隐藏字幕、图文电视) |
|
|
用于无线电调谐器 |
|
|
用于 V4L2 子设备 |
|
|
用于软件定义无线电 (SDR) 调谐器 |
|
|
用于触摸传感器 |
最后一个参数使您可以一定程度地控制使用的设备节点编号(即 videoX
中的 X)。通常,您会传递 -1 以便 v4l2 框架选择第一个可用编号。但有时用户想要选择特定的节点编号。驱动程序通常允许用户通过驱动程序模块选项选择特定的设备节点编号。然后将该编号传递给此函数,并且 video_register_device 将尝试选择该设备节点编号。如果该编号已被使用,则将选择下一个可用的设备节点编号,并且它会向内核日志发送警告。
另一个用例是,如果驱动程序创建了许多设备。在这种情况下,将不同的视频设备放置在单独的范围内可能很有用。例如,视频捕获设备从 0 开始,视频输出设备从 16 开始。因此,您可以使用最后一个参数指定最小设备节点编号,并且 v4l2 框架将尝试选择等于或高于您传递的第一个可用编号。如果失败,它将只选择第一个可用编号。
由于在这种情况下,您不关心有关无法选择指定设备节点编号的警告,因此您可以调用函数 video_register_device_no_warn()
代替。
每当创建设备节点时,还会为您创建一些属性。如果您查看 /sys/class/video4linux
,您会看到这些设备。进入例如 video0
,您将看到 'name'、'dev_debug' 和 'index' 属性。'name' 属性是 video_device 结构体的 'name' 字段。'dev_debug' 属性可用于启用核心调试。有关此方面的更多详细信息,请参见下一节。
'index' 属性是设备节点的索引:对于每次调用 video_register_device()
,索引仅增加 1。您注册的第一个视频设备节点始终以索引 0 开始。
用户可以设置利用 index 属性的 udev 规则来创建奇特的设备名称(例如,用于 MPEG 视频捕获设备节点的 'mpegX
')。
成功注册设备后,您可以使用以下字段
video_device
->vfl_type:传递给video_register_device()
的设备类型。video_device
->minor:分配的设备次要编号。video_device
->num:设备节点编号(即videoX
中的 X)。video_device
->index:设备索引号。
如果注册失败,则需要调用 video_device_release()
以释放已分配的 video_device
结构体,或者释放您自己的结构体(如果 video_device
嵌入其中)。如果注册失败,则永远不会调用 vdev->release()
回调,也不应尝试在注册失败时取消注册设备。
2.4.3. 视频设备调试¶
为 /sys/class/video4linux/<devX>/
中的每个视频、vbi、无线电或 swradio 设备创建的 'dev_debug' 属性允许您启用文件操作的日志记录。
它是一个位掩码,可以设置以下位
掩码 |
描述 |
---|---|
0x01 |
记录 ioctl 名称和错误代码。仅当同时设置了位 0x08 时,才会记录 VIDIOC_(D)QBUF ioctl。 |
0x02 |
记录 ioctl 名称参数和错误代码。仅当同时设置了位 0x08 时,才会记录 VIDIOC_(D)QBUF ioctl。 |
0x04 |
记录文件操作 open、release、read、write、mmap 和 get_unmapped_area。仅当同时设置了位 0x08 时,才会记录读写操作。 |
0x08 |
记录读写文件操作以及 VIDIOC_QBUF 和 VIDIOC_DQBUF ioctl。 |
0x10 |
记录 poll 文件操作。 |
0x20 |
记录控制操作中的错误和消息。 |
2.4.4. 视频设备清理¶
当必须删除视频设备节点时(在卸载驱动程序期间或由于 USB 设备断开连接时),应使用以下命令取消注册它们
这将从 sysfs 中删除设备节点(导致 udev 将它们从 /dev
中删除)。
在 video_unregister_device()
返回后,无法执行任何新的打开操作。但是,对于 USB 设备,某些应用程序可能仍然打开了其中一个设备节点。因此,在取消注册后,所有文件操作(当然,除了 release 之外)也将返回错误。
当视频设备节点的最后一个用户退出时,将调用 vdev->release()
回调,您可以在此处执行最终清理。
如果已初始化,请不要忘记清理与视频设备关联的媒体实体
media_entity_cleanup
(&vdev->entity);
这可以从 release 回调中完成。
2.4.5. 辅助函数¶
有一些有用的辅助函数
文件和
video_device
私有数据
您可以使用以下命令在 video_device 结构体中设置/获取驱动程序私有数据
请注意,您可以安全地在调用 video_register_device()
之前调用 video_set_drvdata()
。
还有这个函数
video_devdata
(struct file
*file);
返回属于文件结构体的 video_device。
video_devdata()
函数将 video_get_drvdata()
与 video_devdata()
结合在一起
video_drvdata
(struct file
*file);
您可以使用以下命令从 video_device
结构体转到 v4l2_device 结构体
struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
设备节点名称
可以使用以下命令检索 video_device
节点内核名称
该名称被用户空间工具(例如 udev)用作提示。在可能的情况下,应使用该函数,而不是访问 video_device::num 和 video_device::minor 字段。
2.4.6. video_device 函数和数据结构¶
-
enum vfl_devnode_type¶
V4L2 设备节点的类型
常量
VFL_TYPE_VIDEO
用于视频输入/输出设备
VFL_TYPE_VBI
用于垂直消隐数据(即隐藏字幕、图文电视)
VFL_TYPE_RADIO
用于无线电调谐器
VFL_TYPE_SUBDEV
用于 V4L2 子设备
VFL_TYPE_SDR
用于软件定义无线电调谐器
VFL_TYPE_TOUCH
用于触摸传感器
VFL_TYPE_MAX
VFL 类型的数量,必须始终在枚举中排在最后
-
enum vfl_devnode_direction¶
标识
struct video_device
是否对应于接收器、发射器或内存到内存设备。
常量
VFL_DIR_RX
设备是接收器。
VFL_DIR_TX
设备是发射器。
VFL_DIR_M2M
设备是内存到内存设备。
注意
如果 enum vfl_devnode_type
为 VFL_TYPE_SUBDEV
,则忽略。
-
enum v4l2_video_device_flags¶
struct video_device
使用的标志
常量
V4L2_FL_REGISTERED
指示
struct video_device
已注册。如果驱动程序想要阻止所有未来的设备访问,则可以清除此标志。它由 video_unregister_device 清除。V4L2_FL_USES_V4L2_FH
指示 file->private_data 指向
struct v4l2_fh
。当调用v4l2_fh_init()
时,核心会设置此标志。所有新驱动程序都应使用它。V4L2_FL_QUIRK_INVERTED_CROP
一些旧的 M2M 驱动程序不正确地使用了 g/s_crop/cropcap:crop 和 compose 互换了。如果设置了这个标志,那么选择目标将在 v4l2-ioctl.c 中的 g/s_crop/cropcap 函数中互换。这允许这些驱动程序正确地实现选择 API,但是旧的 crop API 仍然可以按预期工作,以保持向后兼容性。永远不要为新的驱动程序设置此标志。
V4L2_FL_SUBDEV_RO_DEVNODE
表示视频设备节点以只读模式注册。该标志仅适用于为子设备注册的设备节点,当子设备节点通过
v4l2_device_register_ro_subdev_nodes()
注册时由核心设置,并由子设备 ioctl 处理程序使用以限制对某些 ioctl 调用的访问。
-
struct v4l2_prio_state¶
存储优先级状态
定义:
struct v4l2_prio_state {
atomic_t prios[4];
};
成员
prios
带有元素的数组,用于存储数组优先级
描述
注意
prios 数组的大小与枚举 v4l2_priority
定义的优先级类型数量匹配。
-
void v4l2_prio_init(struct v4l2_prio_state *global)¶
初始化一个
struct v4l2_prio_state
参数
struct v4l2_prio_state *global
指向
struct v4l2_prio_state
的指针
-
int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, enum v4l2_priority new)¶
更改 v4l2 文件句柄优先级
参数
struct v4l2_prio_state *global
指向设备节点的
struct v4l2_prio_state
的指针。enum v4l2_priority *local
指向期望的优先级的指针,如枚举
v4l2_priority
定义的那样enum v4l2_priority new
请求的优先级类型,如枚举
v4l2_priority
定义的那样。
描述
注意
此函数应仅由 V4L2 核心使用。
-
void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)¶
为文件句柄打开实现优先级逻辑
参数
struct v4l2_prio_state *global
指向设备节点的
struct v4l2_prio_state
的指针。enum v4l2_priority *local
指向期望的优先级的指针,如枚举
v4l2_priority
定义的那样
描述
注意
此函数应仅由 V4L2 核心使用。
-
void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)¶
为文件句柄关闭实现优先级逻辑
参数
struct v4l2_prio_state *global
指向设备节点的
struct v4l2_prio_state
的指针。enum v4l2_priority local
要释放的优先级,如枚举
v4l2_priority
定义的那样
描述
注意
此函数应仅由 V4L2 核心使用。
-
enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)¶
返回最大优先级,如存储在 global 数组中的那样。
-
int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)¶
为文件句柄关闭实现优先级逻辑
参数
struct v4l2_prio_state *global
指向设备节点的
struct v4l2_prio_state
的指针。enum v4l2_priority local
期望的优先级,如枚举
v4l2_priority
local 定义的那样
描述
注意
此函数应仅由 V4L2 核心使用。
-
struct v4l2_file_operations¶
V4L2 设备使用的 fs 操作
定义:
struct v4l2_file_operations {
struct module *owner;
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
__poll_t (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
#ifdef CONFIG_COMPAT;
long (*compat_ioctl32) (struct file *, unsigned int, unsigned long);
#endif;
unsigned long (*get_unmapped_area) (struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct file *);
int (*release) (struct file *);
};
成员
owner
指向 struct module 的指针
read
实现 read() 系统调用所需的操作
write
实现 write() 系统调用所需的操作
poll
实现 poll() 系统调用所需的操作
unlocked_ioctl
实现 ioctl() 系统调用所需的操作
compat_ioctl32
在内核使用 64 位指令,但用户空间使用 32 位的情况下实现 ioctl() 系统调用所需的操作。
get_unmapped_area
由 mmap() 系统调用调用,在 %!CONFIG_MMU 时使用
mmap
实现 mmap() 系统调用所需的操作
open
实现 open() 系统调用所需的操作
release
实现 release() 系统调用所需的操作
描述
注意
这些操作用于在 V4L2 驱动程序中实现 fs struct file_operations。V4L2 核心使用子系统所需的一些额外逻辑覆盖 fs ops。
-
struct video_device¶
用于创建和管理 V4L2 设备节点的结构。
定义:
struct video_device {
#if defined(CONFIG_MEDIA_CONTROLLER);
struct media_entity entity;
struct media_intf_devnode *intf_devnode;
struct media_pipeline pipe;
#endif;
const struct v4l2_file_operations *fops;
u32 device_caps;
struct device dev;
struct cdev *cdev;
struct v4l2_device *v4l2_dev;
struct device *dev_parent;
struct v4l2_ctrl_handler *ctrl_handler;
struct vb2_queue *queue;
struct v4l2_prio_state *prio;
char name[64];
enum vfl_devnode_type vfl_type;
enum vfl_devnode_direction vfl_dir;
int minor;
u16 num;
unsigned long flags;
int index;
spinlock_t fh_lock;
struct list_head fh_list;
int dev_debug;
v4l2_std_id tvnorms;
void (*release)(struct video_device *vdev);
const struct v4l2_ioctl_ops *ioctl_ops;
unsigned long valid_ioctls[BITS_TO_LONGS(BASE_VIDIOC_PRIVATE)];
struct mutex *lock;
};
成员
entity
intf_devnode
指向
struct media_intf_devnode
的指针pipe
fops
指向视频设备的
struct v4l2_file_operations
的指针device_caps
在 v4l2_capabilities 中使用的设备功能
dev
视频设备的
struct device
cdev
字符设备
v4l2_dev
指向
struct v4l2_device
父级的指针dev_parent
指向
struct device
父级的指针ctrl_handler
与此设备节点关联的控件处理程序。可以为 NULL。
queue
与此设备节点关联的
struct vb2_queue
。可以为 NULL。prio
指向带有设备优先级状态的
struct v4l2_prio_state
的指针。如果为 NULL,则将使用 v4l2_dev->prio。name
视频设备名称
vfl_type
V4L 设备类型,如
enum vfl_devnode_type
定义的那样vfl_dir
V4L 接收器、发射器或 m2m
minor
设备节点“次设备号”。如果注册失败,则设置为 -1
num
视频设备节点的编号
flags
视频设备标志。使用位操作来设置/清除/测试标志。包含一组
enum v4l2_video_device_flags
。index
用于区分一个物理设备上的多个索引的属性
fh_lock
所有 v4l2_fhs 的锁
fh_list
dev_debug
内部设备调试标志,不供驱动程序使用
tvnorms
支持的电视制式
release
视频设备 release() 回调
ioctl_ops
指向带有 ioctl 回调的
struct v4l2_ioctl_ops
的指针valid_ioctls
包含此设备的有效 ioctl 的位图
lock
指向
struct mutex
序列化锁的指针
描述
注意
仅当无法从 v4l2_dev 推断出 dev_parent 时才设置。
-
media_entity_to_video_device¶
media_entity_to_video_device (__entity)
从嵌入的
struct media_entity
返回一个struct video_device
。
参数
__entity
指向
struct media_entity
的指针
-
to_video_device¶
to_video_device (cd)
从嵌入的
struct device
返回一个struct video_device
。
参数
cd
指向
struct device
的指针
-
int __video_register_device(struct video_device *vdev, enum vfl_devnode_type type, int nr, int warn_if_nr_in_use, struct module *owner)¶
注册 video4linux 设备
参数
struct video_device *vdev
要注册的
struct video_device
enum vfl_devnode_type type
要注册的设备类型,如
enum vfl_devnode_type
定义的那样int nr
期望的设备节点编号:(0 == /dev/video0, 1 == /dev/video1, ..., -1 == 第一个空闲的)
int warn_if_nr_in_use
如果期望的设备节点编号已被使用,并且选择了另一个编号,则发出警告。
struct module *owner
拥有视频设备节点的模块
描述
注册代码根据请求的类型分配次设备号和设备节点编号,并将新的设备节点注册到内核。
此函数假定 struct video_device
在分配时被清零,并且不包含任何过时的数据。
如果找不到空闲的次设备号或设备节点编号,或者设备节点注册失败,则返回错误。
成功时返回 0。
注意
此函数旨在仅在 V4L2 核心中使用。驱动程序应使用 video_register_device()
或 video_register_device_no_warn()
。
-
int video_register_device(struct video_device *vdev, enum vfl_devnode_type type, int nr)¶
注册 video4linux 设备
参数
struct video_device *vdev
要注册的
struct video_device
enum vfl_devnode_type type
要注册的设备类型,如
enum vfl_devnode_type
定义的那样int nr
期望的设备节点编号:(0 == /dev/video0, 1 == /dev/video1, ..., -1 == 第一个空闲的)
描述
在内部,它调用 __video_register_device()
。请参阅其文档以获取更多详细信息。
注意
如果 video_register_device 失败,则不会调用 struct video_device
结构的 release() 回调,因此调用者负责释放任何数据。通常,这意味着您应该在失败时调用 video_device_release()
。
-
int video_register_device_no_warn(struct video_device *vdev, enum vfl_devnode_type type, int nr)¶
注册 video4linux 设备
参数
struct video_device *vdev
要注册的
struct video_device
enum vfl_devnode_type type
要注册的设备类型,如
enum vfl_devnode_type
定义的那样int nr
期望的设备节点编号:(0 == /dev/video0, 1 == /dev/video1, ..., -1 == 第一个空闲的)
描述
此函数与 video_register_device()
相同,只是如果期望的设备节点编号已被使用,则不会发出警告。
在内部,它调用 __video_register_device()
。请参阅其文档以获取更多详细信息。
注意
如果 video_register_device 失败,则不会调用 struct video_device
结构的 release() 回调,因此调用者负责释放任何数据。通常,这意味着您应该在失败时调用 video_device_release()
。
-
void video_unregister_device(struct video_device *vdev)¶
注销视频设备。
参数
struct video_device *vdev
要注册的
struct video_device
描述
如果 vdev == NULL 或如果 video_is_registered()
返回 false,则不执行任何操作。
-
struct video_device *video_device_alloc(void)¶
用于分配
struct video_device
的辅助函数
-
void video_device_release(struct video_device *vdev)¶
用于释放
struct video_device
的辅助函数
-
void video_device_release_empty(struct video_device *vdev)¶
用于实现 video_device->release() 回调的辅助函数。
参数
struct video_device *vdev
指向
struct video_device
的指针
描述
此 release 函数不执行任何操作。
当 video_device 是一个静态全局结构时,应使用它。
注意
拥有静态 video_device 在最佳情况下也是一个可疑的构造。
-
void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd)¶
标记给定的命令未实现。不应使用核心锁定
参数
struct video_device *vdev
指向
struct video_device
的指针unsigned int cmd
ioctl 命令
描述
此函数允许驱动程序仅提供一个 v4l2_ioctl_ops 结构,但根据实际找到的特定卡禁用 ioctl。
注意
必须在 video_register_device 之前调用此函数。另请参阅 determine_valid_ioctls() 的注释。
-
void *video_get_drvdata(struct video_device *vdev)¶
从
struct video_device
获取私有数据。
-
void video_set_drvdata(struct video_device *vdev, void *data)¶
从
struct video_device
设置私有数据。
参数
struct video_device *vdev
指向
struct video_device
的指针void *data
私有数据指针
-
struct video_device *video_devdata(struct file *file)¶
参数
struct file *file
指向
struct file
的指针
-
void *video_drvdata(struct file *file)¶
使用
struct file
从struct video_device
获取私有数据。
-
const char *video_device_node_name(struct video_device *vdev)¶
返回视频设备名称
-
int video_is_registered(struct video_device *vdev)¶
如果
struct video_device
已注册,则返回 true。
参数
struct video_device *vdev
指向
struct video_device
的指针
-
struct dentry *v4l2_debugfs_root(void)¶
返回顶级“v4l2”debugfs 目录的 dentry
参数
void
没有参数
描述
如果此目录尚不存在,则将创建它。
-
int video_device_pipeline_start(struct video_device *vdev, struct media_pipeline *pipe)¶
将管道标记为流式传输
参数
struct video_device *vdev
启动视频设备
struct media_pipeline *pipe
要分配给管道中所有实体的媒体管道。
描述
将通过启用的链接(直接或间接)连接到给定视频设备的所有实体标记为流式传输。给定的管道对象分配给管道中的每个 pad,并存储在 media_pad pipe 字段中。
可以嵌套对此函数的调用,在这种情况下,需要相同数量的 video_device_pipeline_stop()
调用才能停止流式传输。对于 video_device_pipeline_start()
的所有嵌套调用,管道指针必须相同。
视频设备必须包含单个 pad。
这是 media_pipeline_start()
的一个便捷封装。
-
int __video_device_pipeline_start(struct video_device *vdev, struct media_pipeline *pipe)¶
将管道标记为流式传输
参数
struct video_device *vdev
启动视频设备
struct media_pipeline *pipe
要分配给管道中所有实体的媒体管道。
描述
..note:: 这是 video_device_pipeline_start()
的非锁定版本
视频设备必须包含单个 pad。
这是 __media_pipeline_start()
的一个便捷封装。
-
void video_device_pipeline_stop(struct video_device *vdev)¶
将管道标记为非流式传输
参数
struct video_device *vdev
启动视频设备
描述
将通过启用的链接(直接或间接)连接到给定视频设备的所有实体标记为非流式传输。media_pad pipe 字段被重置为 NULL
。
如果多次调用 media_pipeline_start()
,则需要相同数量的对该函数的调用才能将管道标记为非流式传输。
视频设备必须包含单个 pad。
这是 media_pipeline_stop()
的一个便捷封装。
-
void __video_device_pipeline_stop(struct video_device *vdev)¶
将管道标记为非流式传输
参数
struct video_device *vdev
启动视频设备
描述
注意
这是 media_pipeline_stop()
的非锁定版本
视频设备必须包含单个 pad。
这是 __media_pipeline_stop()
的一个便捷封装。
-
int video_device_pipeline_alloc_start(struct video_device *vdev)¶
将管道标记为流式传输
参数
struct video_device *vdev
启动视频设备
描述
video_device_pipeline_alloc_start()
类似于 video_device_pipeline_start()
,但该函数不是在给定的管道上工作,而是将在视频设备已经是管道的一部分时使用现有管道,或者分配一个新的管道。
对 video_device_pipeline_alloc_start()
的调用必须与 video_device_pipeline_stop()
匹配。
-
struct media_pipeline *video_device_pipeline(struct video_device *vdev)¶
获取视频设备所属的媒体管道
参数
struct video_device *vdev
视频设备
描述
此函数返回在通过 video_device_pipeline_start()
构造管道时与视频设备关联的媒体管道。指针在调用 video_device_pipeline_stop()
之前仍然有效。
视频设备必须包含单个 pad。
这是 media_entity_pipeline()
的一个便捷封装。
返回
视频设备所属的 media_pipeline,如果视频设备不属于任何管道,则返回 NULL。