7.49. ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU

7.49.1. 名称

VIDIOC_QUERYCTRL - VIDIOC_QUERY_EXT_CTRL - VIDIOC_QUERYMENU - 枚举控件和菜单控件项

7.49.2. 概要

int ioctl(int fd, int VIDIOC_QUERYCTRL, struct v4l2_queryctrl *argp)

VIDIOC_QUERY_EXT_CTRL

int ioctl(int fd, VIDIOC_QUERY_EXT_CTRL, struct v4l2_query_ext_ctrl *argp)

VIDIOC_QUERYMENU

int ioctl(int fd, VIDIOC_QUERYMENU, struct v4l2_querymenu *argp)

7.49.3. 参数

fd

open() 返回的文件描述符。

argp

指向 struct v4l2_queryctrl, v4l2_query_ext_ctrlv4l2_querymenu 的指针(取决于 ioctl)。

7.49.4. 描述

要查询控件的属性,应用程序应设置 struct v4l2_queryctrlid 字段,并调用 VIDIOC_QUERYCTRL ioctl,并将指向此结构的指针作为参数传递。驱动程序会填充该结构的其他字段,或者当 id 无效时返回 EINVAL 错误代码。

可以通过使用从 V4L2_CID_BASE 开始到不包括 V4L2_CID_LASTP1 的连续 id 值调用 VIDIOC_QUERYCTRL 来枚举控件。如果不支持此范围内的某个控件,驱动程序可能会返回 EINVAL。此外,应用程序可以通过从 V4L2_CID_PRIVATE_BASE 开始并递增 id 直到驱动程序返回 EINVAL 来枚举此规范中未定义的私有控件。

在这两种情况下,当驱动程序在 flags 字段中设置 V4L2_CTRL_FLAG_DISABLED 标志时,此控件将永久禁用,应用程序应忽略它。[1]

当应用程序将 idV4L2_CTRL_FLAG_NEXT_CTRL 进行或运算时,驱动程序将返回下一个受支持的非复合控件,如果没有则返回 EINVAL。此外,可以指定 V4L2_CTRL_FLAG_NEXT_COMPOUND 标志来枚举所有复合控件(即类型 ≥ V4L2_CTRL_COMPOUND_TYPES 和/或数组控件,换句话说,包含多个值的控件)。指定 V4L2_CTRL_FLAG_NEXT_CTRLV4L2_CTRL_FLAG_NEXT_COMPOUND 以便枚举所有控件,无论是否复合。尚不支持这些标志的驱动程序始终返回 EINVAL

引入 VIDIOC_QUERY_EXT_CTRL ioctl 是为了更好地支持可以使用复合类型的控件,并公开无法在 struct v4l2_queryctrl 中返回的其他控件信息,因为该结构已满。

VIDIOC_QUERY_EXT_CTRL 的使用方式与 VIDIOC_QUERYCTRL 相同,只是 reserved 数组也必须清零。

菜单控件需要额外的信息:菜单项的名称。要查询它们,应用程序应设置 struct v4l2_querymenuidindex 字段,并调用 VIDIOC_QUERYMENU ioctl,并将指向此结构的指针作为参数传递。驱动程序会填充该结构的其他字段,或者当 idindex 无效时返回 EINVAL 错误代码。通过使用 struct v4l2_queryctrl minimummaximum(包括)的连续 index 值调用 VIDIOC_QUERYMENU 来枚举菜单项。

注意

minimummaximum 之间的一些索引处,VIDIOC_QUERYMENU 可能会返回 EINVAL 错误代码。在这种情况下,此驱动程序不支持该特定菜单项。另请注意,minimum 值不一定是 0。

另请参阅 用户控件 中的示例。

struct v4l2_queryctrl

__u32

id

标识控件,由应用程序设置。有关预定义的 ID,请参见控件 ID。当 ID 与 V4L2_CTRL_FLAG_NEXT_CTRL 进行或运算时,驱动程序会清除该标志并返回 ID 更高的第一个控件。尚不支持此标志的驱动程序始终返回 EINVAL 错误代码。

__u32

type

控件的类型,请参见 v4l2_ctrl_type

__u8

name[32]

控件的名称,以 NUL 结尾的 ASCII 字符串。此信息供用户使用。

__s32

minimum

最小值,包括在内。此字段为控件提供了下限。请参阅枚举 v4l2_ctrl_type,了解如何为每个可能的控件类型使用最小值。请注意,这是一个带符号的 32 位值。

__s32

maximum

最大值,包括在内。此字段为控件提供了上限。请参阅枚举 v4l2_ctrl_type,了解如何为每个可能的控件类型使用最大值。请注意,这是一个带符号的 32 位值。

__s32

step

此字段为控件提供了步长。请参阅枚举 v4l2_ctrl_type,了解如何为每个可能的控件类型使用步长值。请注意,这是一个无符号的 32 位值。

通常,驱动程序不应缩放硬件控件值。例如,当 nameid 暗示特定单位,而硬件实际上只接受该单位的倍数时,这可能是必要的。如果是这样,驱动程序必须注意在缩放时正确舍入值,以便在重复的读写周期中不会累积错误。

此字段给出了实际影响硬件的整数控件的最小更改。当用户可以通过键盘或 GUI 按钮而不是滑块来更改控件时,通常需要此信息。例如,当硬件寄存器接受值 0-511,而驱动程序报告 0-65535 时,步长应为 128。

请注意,尽管有符号,但步长值应始终为正。

__s32

default_value

V4L2_CTRL_TYPE_INTEGER_BOOLEAN_BITMASK_MENU_INTEGER_MENU 控件的默认值。对其他类型的控件无效。

注意

驱动程序仅在首次加载驱动程序时将其控件重置为默认值,之后不会重置。

__u32

flags

控制标志,请参阅控制标志

__u32

保留[2]

为未来扩展保留。驱动程序必须将数组设置为零。

struct v4l2_query_ext_ctrl

__u32

id

标识由应用程序设置的控件。有关预定义的 ID,请参阅控制 ID。当 ID 与 V4L2_CTRL_FLAG_NEXT_CTRL 进行或运算时,驱动程序会清除该标志并返回 ID 较高的第一个非复合控件。当 ID 与 V4L2_CTRL_FLAG_NEXT_COMPOUND 进行或运算时,驱动程序会清除该标志并返回 ID 较高的第一个复合控件。同时设置这两者将获取 ID 较高的第一个控件(复合或非复合)。

__u32

type

控件的类型,请参见 v4l2_ctrl_type

char

name[32]

控件的名称,以 NUL 结尾的 ASCII 字符串。此信息供用户使用。

__s64

minimum

最小值,包含。此字段给出控件的下限。请参阅枚举v4l2_ctrl_type,了解如何为每个可能的控件类型使用最小值。请注意,这是一个有符号的 64 位值。

__s64

maximum

最大值,包含。此字段给出控件的上限。请参阅枚举v4l2_ctrl_type,了解如何为每个可能的控件类型使用最大值。请注意,这是一个有符号的 64 位值。

__u64

step

此字段给出控件的步长。请参阅枚举v4l2_ctrl_type,了解如何为每个可能的控件类型使用步长值。请注意,这是一个无符号的 64 位值。

通常,驱动程序不应缩放硬件控件值。例如,当 nameid 暗示特定单位,而硬件实际上只接受该单位的倍数时,这可能是必要的。如果是这样,驱动程序必须注意在缩放时正确舍入值,以便在重复的读写周期中不会累积错误。

此字段给出了实际影响硬件的整数控件的最小更改。当用户可以通过键盘或 GUI 按钮而不是滑块来更改控件时,通常需要此信息。例如,当硬件寄存器接受值 0-511,而驱动程序报告 0-65535 时,步长应为 128。

__s64

default_value

V4L2_CTRL_TYPE_INTEGER_INTEGER64_BOOLEAN_BITMASK_MENU_INTEGER_MENU_U8_U16 控件的默认值。对其他类型的控件无效。

注意

驱动程序仅在首次加载驱动程序时将其控件重置为默认值,之后不会重置。

__u32

flags

控制标志,请参阅控制标志

__u32

elem_size

数组中单个元素的大小(以字节为单位)。给定指向三维数组的字符指针 p,您可以找到单元格 (z, y, x) 的位置,如下所示:p + ((z * dims[1] + y) * dims[0] + x) * elem_sizeelem_size 始终有效,即使控件不是数组也是如此。对于字符串控件,elem_size 等于 maximum + 1

__u32

elems

N 维数组中的元素数量。如果此控件不是数组,则 elems 为 1。 elems 字段永远不能为 0。

__u32

nr_of_dims

N 维数组中的维度数。如果此控件不是数组,则此字段为 0。

__u32

dims[V4L2_CTRL_MAX_DIMS]

每个维度的大小。此数组的前 nr_of_dims 个元素必须是非零的,所有剩余元素必须为零。

__u32

保留[32]

为未来扩展保留。应用程序和驱动程序必须将数组设置为零。

struct v4l2_querymenu

__u32

id

标识控件,由应用程序从相应的 struct v4l2_queryctrl id 设置。

__u32

index

菜单项的索引,从零开始,由应用程序设置。

union {

(匿名)

__u8

name[32]

菜单项的名称,以 NUL 结尾的 ASCII 字符串。此信息供用户使用。此字段对于 V4L2_CTRL_TYPE_MENU 类型控件有效。

__s64

value

整数菜单项的值。此字段对于 V4L2_CTRL_TYPE_INTEGER_MENU 类型控件有效。

}

__u32

保留

为未来扩展保留。驱动程序必须将数组设置为零。

type v4l2_ctrl_type
enum v4l2_ctrl_type

类型

minimum

step

maximum

描述

V4L2_CTRL_TYPE_INTEGER

任意

任意

任意

一个整数值控件,范围从最小值到最大值(含)。步长值表示值之间的增量。

V4L2_CTRL_TYPE_BOOLEAN

0

1

1

一个布尔值控件。零对应于“禁用”,一表示“启用”。

V4L2_CTRL_TYPE_MENU

≥ 0

1

N-1

该控件有 N 个选项的菜单。可以使用 VIDIOC_QUERYMENU ioctl 枚举菜单项的名称。

V4L2_CTRL_TYPE_INTEGER_MENU

≥ 0

1

N-1

该控件有 N 个选项的菜单。可以使用 VIDIOC_QUERYMENU ioctl 枚举菜单项的值。这类似于 V4L2_CTRL_TYPE_MENU,不同之处在于,菜单项不是字符串,而是有符号的 64 位整数。

V4L2_CTRL_TYPE_BITMASK

0

n/a

任意

一个位掩码字段。最大值是可以使用的位集合,所有其他位都必须为 0。最大值被解释为 __u32,允许在位掩码中使用位 31。

V4L2_CTRL_TYPE_BUTTON

0

0

0

一个在设置时执行操作的控件。驱动程序必须忽略 VIDIOC_S_CTRL 传递的值,并在尝试 VIDIOC_G_CTRL 时返回 EACCES 错误代码。

V4L2_CTRL_TYPE_INTEGER64

任意

任意

任意

一个 64 位整数值控件。无法使用 VIDIOC_QUERYCTRL 查询最小值、最大值和步长。只有 VIDIOC_QUERY_EXT_CTRL 可以检索 64 位最小值/最大值/步长值,当使用 VIDIOC_QUERYCTRL 时,它们应被解释为 n/a。

V4L2_CTRL_TYPE_STRING

≥ 0

≥ 1

≥ 0

最小和最大字符串长度。步长表示字符串的长度必须为(最小 + N * 步长)个字符,其中 N ≥ 0。这些长度不包括终止零,因此为了将长度为 8 的字符串传递给 VIDIOC_S_EXT_CTRLS,您需要将 struct v4l2_ext_controlsize 字段设置为 9。对于 VIDIOC_G_EXT_CTRLS,您可以将 size 字段设置为 maximum + 1。使用的字符编码将取决于字符串控件本身,并且应该是控件文档的一部分。

V4L2_CTRL_TYPE_CTRL_CLASS

n/a

n/a

n/a

这不是一个控件。当使用等于控制类代码(请参阅控制类)+ 1 的控制 ID 调用 VIDIOC_QUERYCTRL 时,ioctl 会返回控制类的名称和此控制类型。不支持此功能的较旧驱动程序会返回 EINVAL 错误代码。

V4L2_CTRL_TYPE_U8

任意

任意

任意

一个无符号的 8 位值控件,范围从最小值到最大值(含)。步长值表示值之间的增量。

V4L2_CTRL_TYPE_U16

任意

任意

任意

一个无符号的 16 位值控件,范围从最小值到最大值(含)。步长值表示值之间的增量。

V4L2_CTRL_TYPE_U32

任意

任意

任意

一个无符号的 32 位值控件,范围从最小值到最大值(含)。步长值表示值之间的增量。

V4L2_CTRL_TYPE_MPEG2_QUANTISATION

n/a

n/a

n/a

一个 struct v4l2_ctrl_mpeg2_quantisation,包含用于无状态视频解码器的 MPEG-2 量化矩阵。

V4L2_CTRL_TYPE_MPEG2_SEQUENCE

n/a

n/a

n/a

一个 struct v4l2_ctrl_mpeg2_sequence,包含用于无状态视频解码器的 MPEG-2 序列参数。

V4L2_CTRL_TYPE_MPEG2_PICTURE

n/a

n/a

n/a

一个 struct v4l2_ctrl_mpeg2_picture,包含用于无状态视频解码器的 MPEG-2 图片参数。

V4L2_CTRL_TYPE_AREA

n/a

n/a

n/a

一个 struct v4l2_area,包含矩形区域的宽度和高度。单位取决于用例。

V4L2_CTRL_TYPE_H264_SPS

n/a

n/a

n/a

一个 struct v4l2_ctrl_h264_sps,包含用于无状态视频解码器的 H264 序列参数。

V4L2_CTRL_TYPE_H264_PPS

n/a

n/a

n/a

一个 struct v4l2_ctrl_h264_pps,包含用于无状态视频解码器的 H264 图片参数。

V4L2_CTRL_TYPE_H264_SCALING_MATRIX

n/a

n/a

n/a

一个 struct v4l2_ctrl_h264_scaling_matrix,包含用于无状态视频解码器的 H264 缩放矩阵。

V4L2_CTRL_TYPE_H264_SLICE_PARAMS

n/a

n/a

n/a

一个 struct v4l2_ctrl_h264_slice_params,包含用于无状态视频解码器的 H264 片段参数。

V4L2_CTRL_TYPE_H264_DECODE_PARAMS

n/a

n/a

n/a

一个 struct v4l2_ctrl_h264_decode_params,包含用于无状态视频解码器的 H264 解码参数。

V4L2_CTRL_TYPE_FWHT_PARAMS

n/a

n/a

n/a

一个 struct v4l2_ctrl_fwht_params,包含用于无状态视频解码器的 FWHT 参数。

V4L2_CTRL_TYPE_HEVC_SPS

n/a

n/a

n/a

一个 struct v4l2_ctrl_hevc_sps,包含用于无状态视频解码器的 HEVC 序列参数集。

V4L2_CTRL_TYPE_HEVC_PPS

n/a

n/a

n/a

一个 struct v4l2_ctrl_hevc_pps,包含用于无状态视频解码器的 HEVC 图片参数集。

V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS

n/a

n/a

n/a

一个结构体 v4l2_ctrl_hevc_slice_params,包含用于无状态视频解码器的 HEVC 片参数。

V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX

n/a

n/a

n/a

一个结构体 v4l2_ctrl_hevc_scaling_matrix,包含用于无状态视频解码器的 HEVC 缩放矩阵。

V4L2_CTRL_TYPE_VP8_FRAME

n/a

n/a

n/a

一个结构体 v4l2_ctrl_vp8_frame,包含用于无状态视频解码器的 VP8 帧参数。

V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS

n/a

n/a

n/a

一个结构体 v4l2_ctrl_hevc_decode_params,包含用于无状态视频解码器的 HEVC 解码参数。

V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR

n/a

n/a

n/a

一个结构体 v4l2_ctrl_vp9_compressed_hdr,包含用于无状态视频解码器的 VP9 概率更新。

V4L2_CTRL_TYPE_VP9_FRAME

n/a

n/a

n/a

一个结构体 v4l2_ctrl_vp9_frame,包含用于无状态视频解码器的 VP9 帧解码参数。

V4L2_CTRL_TYPE_AV1_SEQUENCE

n/a

n/a

n/a

一个结构体 v4l2_ctrl_av1_sequence,包含用于无状态视频解码器的 AV1 序列 OBU 解码参数。

V4L2_CTRL_TYPE_AV1_TILE_GROUP_ENTRY

n/a

n/a

n/a

一个结构体 v4l2_ctrl_av1_tile_group_entry,包含用于无状态视频解码器的 AV1 图块组 OBU 解码参数。

V4L2_CTRL_TYPE_AV1_FRAME

n/a

n/a

n/a

一个结构体 v4l2_ctrl_av1_frame,包含用于无状态视频解码器的 AV1 帧/帧头 OBU 解码参数。

V4L2_CTRL_TYPE_AV1_FILM_GRAIN

n/a

n/a

n/a

一个结构体 v4l2_ctrl_av1_film_grain,包含用于无状态视频解码器的 AV1 胶片颗粒参数。

控制标志

V4L2_CTRL_FLAG_DISABLED

0x0001

此控件被永久禁用,应用程序应忽略它。任何尝试更改控件的操作都将导致 EINVAL 错误代码。

V4L2_CTRL_FLAG_GRABBED

0x0002

此控件暂时不可更改,例如,因为另一个应用程序接管了相应资源的控制权。此类控件可能会在用户界面中特殊显示。尝试更改控件可能会导致 EBUSY 错误代码。

V4L2_CTRL_FLAG_READ_ONLY

0x0004

此控件是永久只读的。任何尝试更改控件的操作都将导致 EINVAL 错误代码。

V4L2_CTRL_FLAG_UPDATE

0x0008

提示更改此控件可能会影响同一控制类中其他控件的值。应用程序应相应地更新其用户界面。

V4L2_CTRL_FLAG_INACTIVE

0x0010

此控件不适用于当前配置,应在用户界面中相应地显示。例如,当使用另一个控件选择 MPEG 音频编码级别 1 时,可能会在 MPEG 音频级别 2 比特率控件上设置此标志。

V4L2_CTRL_FLAG_SLIDER

0x0020

提示此控件最好在用户界面中表示为滑块状元素。

V4L2_CTRL_FLAG_WRITE_ONLY

0x0040

此控件是永久只写的。任何尝试读取控件的操作都将导致 EACCES 错误代码。对于相对控件或操作控件,此标志通常存在,其中写入一个值将导致设备执行给定的操作(例如,电机控制),但无法返回有意义的值。

V4L2_CTRL_FLAG_VOLATILE

0x0080

此控件是易失的,这意味着控件的值会持续变化。一个典型的例子是设备处于自动增益模式时的当前增益值。在这种情况下,硬件会根据光照条件计算增益值,而光照条件会随时间变化。

注意

除非还设置了 V4L2_CTRL_FLAG_EXECUTE_ON_WRITE,否则将忽略为易失控件设置的新值。为易失控件设置新值永远不会触发 V4L2_EVENT_CTRL_CH_VALUE 事件。

V4L2_CTRL_FLAG_HAS_PAYLOAD

0x0100

此控件具有指针类型,因此必须使用结构体 v4l2_ext_control 的指针字段之一访问其值。对于数组、字符串或具有复合类型的控件,将设置此标志。在所有情况下,您都必须设置一个指向包含控件有效负载的内存的指针。

V4L2_CTRL_FLAG_EXECUTE_ON_WRITE

0x0200

即使提供给控件的值保持不变,该值也会传播到驱动程序。当控件表示硬件上的操作时,这是必需的。例如:清除错误标志或触发闪光灯。所有类型为 V4L2_CTRL_TYPE_BUTTON 的控件都设置了此标志。

V4L2_CTRL_FLAG_MODIFY_LAYOUT

0x0400

更改此控件的值可能会修改缓冲区(对于视频设备)或媒体总线格式(对于子设备)的布局。

一个典型的例子是 V4L2_CID_ROTATE 控件。

请注意,通常带有此标志的控件也会在分配缓冲区或流式传输正在进行时设置 V4L2_CTRL_FLAG_GRABBED 标志,因为大多数驱动程序不支持在这种情况下更改格式。

V4L2_CTRL_FLAG_DYNAMIC_ARRAY

0x0800

此控件是动态大小的一维数组。它的行为与常规数组相同,只是 elems 字段报告的元素数量在 1 和 dims[0] 之间。因此,使用不同大小的数组设置控件将在之后查询控件时更改 elems 字段。

7.49.5. 返回值

成功时返回 0,发生错误时返回 -1,并设置 errno 变量。通用错误代码在 通用错误代码 章节中描述。

EINVAL

结构体 v4l2_queryctrl id 无效。结构体 v4l2_querymenu id 无效,或者 index 超出范围(小于 minimum 或大于 maximum),或者驱动程序不支持此特定菜单项。

EACCES

尝试读取只写控件。