函数使用: int ioctl(int fd, int request, struct v4l2_capability *argp);
struct v4l2_capability
{
u8 driver[16]; // 驱动名字
u8 card[32]; // 设备名字
u8 bus_info[32]; // 设备在系统中的位置
u32 version;// 驱动版本号
u32 capabilities;// 设备支持的操作
u32 reserved[4]; // 保留字段
};
struct v4l2_capability cap;
ret = ioctl(fd,VIDIOC_QUERYCAP,&cap);
if (ret < 0) {
LOG("VIDIOC_QUERYCAP failed (%d)\n", ret);
return ret;
}
capabilities 常用值:
V4L2_CAP_VIDEO_CAPTURE (是否支持图像获取)
struct v4l2_capability cap;
ioctl(fd,VIDIOC_QUERYCAP,&cap);
printf(“Driver Name:%s\nCard Name:%s\nBus info:%s\nDriver Version:%u.%u.%u\n”,cap.driver,cap.card,cap.bus_info,cap.capabilities);
V4L2_BUF_TYPE_VIDEO_CAPTURE (获取设备支持的分辨率)
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;//初始化
struct v4l2_fmtdesc fmt_1;
struct v4l2_frmsizeenum frmsize;
struct v4l2_frmivalenum frmival;
fmt_1.index = 0; //索引
fmt_1.type = type;
while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt_1) >= 0) {
frmsize.pixel_format = fmt_1.pixelformat;
frmsize.index = 0;
while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0){
if(frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE){
printf("line:%d %dx%d\n",__LINE__, frmsize.discrete.width, frmsize.discrete.height);
}else if(frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE){
printf("line:%d %dx%d\n",__LINE__, frmsize.discrete.width, frmsize.discrete.height);
}
frmsize.index++;
}
fmt_1.index++;
}
}
//------2------//
struct v4l2_capability cap;
memset(&cap, 0, sizeof(cap));
/* 获取设备支持的操作 */
if(ioctl(dev->fd, VIDIOC_QUERYCAP, &cap) < 0){
if(EINVAL == errno){ /*EINVAL为返回的错误值*/
printf(stderr,"%s is no V4L2 device\n", dev->dev);
return TFAIL;
}
else
{
printf(stderr,"%s is not V4L2 device,unknow error\n", dev->dev);
return TFAIL;
}
}
//获取成功,检查是否有视频捕获功能
if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)){
printf(stderr, "%s is no video capture device\n",dev->dev);
return TFAIL;
}
/* streaming I/O ioctls */
if(!(cap.capabilities & V4L2_CAP_STREAMING)){
printf(stderr, "%s does not support streaming i/o\n",dev->dev);
return TFAIL;
}
static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_capability *cap = (struct v4l2_capability *)arg;
struct video_device *vfd = video_devdata(file);
int ret;
cap->version = LINUX_VERSION_CODE;
cap->device_caps = vfd->device_caps;
cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS;
ret = ops->vidioc_querycap(file, fh, cap);
cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
/*
* Drivers MUST fill in device_caps, so check for this and
* warn if it was forgotten.
*/
WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) ||
!cap->device_caps, "Bad caps for driver %s, %x %x",
cap->driver, cap->capabilities, cap->device_caps);
cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
return ret;
}
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *vc)
{
struct usb_usbvision *usbvision = video_drvdata(file);
struct video_device *vdev = video_devdata(file);
// 这里只是将一些信息写回用户空间而已,非常简单
strlcpy(vc->driver, "USBVision", sizeof(vc->driver));
strlcpy(vc->card,
usbvision_device_data[usbvision->dev_model].model_string,
sizeof(vc->card));
usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
vc->device_caps = usbvision->have_tuner ? V4L2_CAP_TUNER : 0;
if (vdev->vfl_type == VFL_TYPE_GRABBER)
vc->device_caps |= V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
else
vc->device_caps |= V4L2_CAP_RADIO;
vc->capabilities = vc->device_caps | V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS;
if (usbvision_device_data[usbvision->dev_model].radio)
vc->capabilities |= V4L2_CAP_RADIO;
return 0;
}
/* Values for 'capabilities' field */
#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */
#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */