培训机构学习总结
PS:
#include
在/usr/include/videodev2.h
可以查看相对应的结构体
确定操作的设备文件是摄像头相关的
struct v4l2_capability cap;
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0)
printf("driver: %s\n", cap.driver); // uvcvideo是linux下通用的usb摄像头驱动
printf("card: %s\n", cap.card); //获取设备名
printf("bus info: %s\n", cap.bus_info); //获取总线信息
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) //判断摄像头是否可用
{
printf("invalid camera");
return 3;
}
查询此设备文件对应的摄像头驱动支持的摄像头个数
struct v4l2_input inp;
for (i = 0; ; i++)
{
inp.index = i;
if (ioctl(fd, VIDIOC_ENUMINPUT, &inp) < 0)
break;
printf("input %d : %s\n", i, inp.name);
}
//如果支持多个摄像头,可通过ioctl的VIDIOC_S_INPUT指定使用第几个摄像头
查询摄像头支持的图像数据格式,分辨率,帧率
struct v4l2_fmtdesc fmtd; //存的是摄像头支持的传输格式
struct v4l2_frmsizeenum frmsize; //存的是摄像头,对应的图片格式所支持的分辨率
struct v4l2_frmivalenum framival; //存的时,对应的图片格式,分辨率所支持的帧率
for (i = 0; ; i++)
{
fmtd.index = i;
fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(fd, VIDIOC_ENUM_FMT, &fmtd) < 0)
break;
printf("fmt %d: %s\n", i, fmtd.description);
// 查询这种图像数据格式下支持的分辨率
for (j = 0; ; j++)
{
frmsize.index = j;
frmsize.pixel_format = fmtd.pixelformat;
//fmtd.pixelformat 四字符代码(不知道是什么鬼,总之是识别图片格式)
if (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) < 0)
break;
printf("w = %d, h = %d\n", frmsize.discrete.width, frmsize.discrete.height);
//查询在这种图像数据格式下这种分辨率支持的帧率
for (k = 0; ; k++)
{
framival.index = k;
framival.pixel_format = fmtd.pixelformat;
framival.width = frmsize.discrete.width;
framival.height = frmsize.discrete.height;
if (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &framival) < 0)
break;
//下面是帧率的获取
printf("frame interval: %d, %d\n", framival.discrete.numerator, framival.discrete.denominator);
}
}
}
源码
#include
#include
#include
#include
int main(void)
{
int fd, i, j, k;
fd = open("/dev/video0", O_RDWR);
if (fd < 0)
{
perror("open dev");
return 1;
}
// /dev/video? 这些设备文件是视频相关驱动产生的,摄像头只是视频设备中的一种,除此外还有硬件编解码的设备,图形加速等高设备。所以/dev/video?设备文件不一定是摄像头相关的设备文件.
//检查打开的设备文件是不是摄像头的设备文件.
struct v4l2_capability cap;
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0)
{
perror("query cap");
return 2;
}
printf("driver: %s\n", cap.driver); // uvcvideo是linux下通用的usb摄像头驱动
printf("card: %s\n", cap.card);
printf("bus info: %s\n", cap.bus_info);
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
{
printf("invalid camera\n");
return 3;
}
//
//查询此设备文件对应的摄像头驱动支持的摄像头个数
struct v4l2_input inp;
for (i = 0; ; i++)
{
inp.index = i;
if (ioctl(fd, VIDIOC_ENUMINPUT, &inp) < 0)
break;
printf("input %d : %s\n", i, inp.name);
}
//如果支持多个摄像头,可通过ioctl的VIDIOC_S_INPUT指定使用第几个摄像头
//查询摄像头支持的图像数据格式
struct v4l2_fmtdesc fmtd; //存的是摄像头支持的传输格式
struct v4l2_frmsizeenum frmsize; //存的是摄像头,对应的图片格式所支持的分辨率
struct v4l2_frmivalenum framival; //存的时,对应的图片格式,分辨率所支持的帧率
for (i = 0; ; i++)
{
fmtd.index = i;
fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(fd, VIDIOC_ENUM_FMT, &fmtd) < 0)
break;
printf("fmt %d: %s\n", i, fmtd.description);
// 查询这种图像数据格式下支持的分辨率
for (j = 0; ; j++)
{
frmsize.index = j;
frmsize.pixel_format = fmtd.pixelformat;
//fmtd.pixelformat 四字符代码(不知道是什么鬼,总之是识别图片格式)
if (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) < 0)
break;
printf("w = %d, h = %d\n", frmsize.discrete.width, frmsize.discrete.height);
//查询在这种图像数据格式下这种分辨率支持的帧率
for (k = 0; ; k++)
{
framival.index = k;
framival.pixel_format = fmtd.pixelformat;
framival.width = frmsize.discrete.width;
framival.height = frmsize.discrete.height;
if (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &framival) < 0)
break;
//下面是帧率的获取
printf("frame interval: %d, %d\n", framival.discrete.numerator, framival.discrete.denominator);
}
}
}
close(fd);
return 0;
}