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
,则它将使用v4l2_device
中的struct v4l2_prio_state
。如果要为每个(组)设备节点具有单独的优先级状态,则可以将其指向您自己的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
,那么您应该在您的 v4l2_file_operations
结构体中将 video_device
->unlocked_ioctl 设置为 video_ioctl2()
。
在某些情况下,您希望告诉核心,您在 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
父设备的 mdev 字段不是 NULL
,则视频设备实体将自动向媒体设备注册。
注册哪个设备取决于 type 参数。存在以下类型
设备名称 |
用法 |
|
---|---|---|
|
|
用于视频输入/输出设备 |
|
|
用于垂直消隐数据(即,隐藏式字幕、图文电视) |
|
|
用于无线电调谐器 |
|
|
用于 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. 视频设备调试¶
为每个视频、vbi、无线电或软件无线电设备创建的 ‘dev_debug’ 属性位于 /sys/class/video4linux/<devX>/
中,它允许你启用文件操作的日志记录。
它是一个位掩码,可以设置以下位:
掩码 |
描述 |
---|---|
0x01 |
记录 ioctl 名称和错误代码。仅当同时设置了 0x08 位时,才会记录 VIDIOC_(D)QBUF ioctl。 |
0x02 |
记录 ioctl 名称参数和错误代码。仅当同时设置了 0x08 位时,才会记录 VIDIOC_(D)QBUF ioctl。 |
0x04 |
记录文件操作 open、release、read、write、mmap 和 get_unmapped_area。仅当同时设置了 0x08 位时,才会记录 read 和 write 操作。 |
0x08 |
记录 read 和 write 文件操作以及 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:裁剪和合成被交换。如果设置此标志,则 v4l2-ioctl.c 中的 g/s_crop/cropcap 函数中的选择目标将被交换。这允许这些驱动程序正确实现选择 API,但旧的裁剪 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 *);
};
成员
拥有者
指向 struct module 的指针
读取
实现 read() 系统调用所需的操作
写入
实现 write() 系统调用所需的操作
轮询
实现 poll() 系统调用所需的操作
unlocked_ioctl
实现 ioctl() 系统调用所需的操作
compat_ioctl32
在内核使用 64 位指令,但用户空间使用 32 位的情况下,实现 ioctl() 系统调用所需的操作。
get_unmapped_area
由 mmap() 系统调用调用,当 %!CONFIG_MMU 时使用
mmap
实现 mmap() 系统调用所需的操作
打开
实现 open() 系统调用所需的操作
释放
实现 release() 系统调用所需的操作
描述
注意
这些操作用于在 V4L2 驱动程序中实现 fs struct file_operations。V4L2 核心使用子系统所需的一些额外逻辑覆盖 fs 操作。
-
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;
};
成员
实体
intf_devnode
指向
struct media_intf_devnode
的指针管道
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。
队列
与此设备节点关联的
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
struct v4l2_fh
的列表dev_debug
内部设备调试标志,驱动程序不得使用
tvnorms
支持的电视标准
释放
视频设备 release() 回调
ioctl_ops
指向带有 ioctl 回调的
struct v4l2_ioctl_ops
的指针valid_ioctls
此设备的有效 ioctl 的位图
锁
指向
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
的指针
描述
此释放函数不执行任何操作。
当 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 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。