mipi接口的摄像头驱动并发布话题

  • Post author:
  • Post category:其他


情况: 需要跑ORBSLAM, 之前一直使用USB接口的相机, 打开摄像头一般使用的是ROS下的usb-cam-node进行驱动,采集图像并发布成topic的形式,或者使用opencv的videoCapture进行图像的捕捉;

因为某些原因需要将usb接口的camera转换成mipi接口的相机; 还是使用了原先usb_cam_node进行摄像头的驱动,输入/dev/video, 对应的width和height之后,结果出现了如下的提示:

最主要的就是[ERROR], 提示如下:

[ERROR] [1608815170.494006746]: /dev/video4 is no video capture device capability is 2216693760

在usb_cam_node中找到对应的代码如下:

  if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
  {
    ROS_ERROR_STREAM(camera_dev_ << " is no video capture device capability is " <<cap.capabilities );
    exit(EXIT_FAILURE);
  }

这里的cap是v4l2_capability类型的变量,

struct v4l2_capability
{
  u8 driver[16]; // 驱动名字
  u8 card[32]; // 设备名字
  u8 bus_info[32]; // 设备在系统中的位置
  u32 version; // 驱动版本号
  u32 capabilities; // 设备支持的操作
  u32 reserved[4]; // 保留字段
};

将2216693760转换成十六进制即为: 0x84201000, 对应到v4l2_capability所表示的devide的所支持的操作分别是:

V4L2_CAP_DEVICE_CAPS
V4L2_CAP_STREAMING
V4L2_CAP_EXT_PIX_FORMAT
V4L2_CAP_VIDEO_CAPTURE_MPLANE

其中,最后一项操作的解释如下:

/* Is a video capture device that supports multiplanar formats */
#define V4L2_CAP_VIDEO_CAPTURE_MPLANE	0x00001000

而对应到usb_cam.cpp中报错部分的代码, 需要的是支持下面两种操作的设备:

V4L2_CAP_VIDEO_CAPTURE
V4L2_CAP_STREAMING

接下来对V4L2一个简单的总结:

Video for Linuxtwo(Video4Linux2)简称V4L2,是V4L的改进版。V4L2是linux操作系统下用于采集图片、视频和音频数据的API接口,配合适当的视频采集设备和相应的驱动程序,可以实现图片、视频、音频等的采集。在远程会议、可视电话、视频监控系统和嵌入式多媒体终端中都有广泛的应用。

在Linux下,所有外设都被看成一种特殊的文件,成为“设备文件”,可以象访问普通文件一样对其进行读写。一般来说,采用V4L2驱动的摄像头设备文件是/dev/video0。V4L2支持两种方式来采集图像:内存映射方式(mmap)和直接读取方式(read)。V4L2在include/linux/videodev.h文件中定义了一些重要的数据结构,在采集图像的过程中,就是通过对这些数据的操作来获得最终的图像数据。Linux系统V4L2的能力可在Linux内核编译阶段配置,默认情况下都有此开发接口。

应用程序通过V4L2进行视频采集的原理

V4L2支持


内存映射方式


(mmap)和


直接读取方式


(read)来采集数据,前者一般用于连续视频数据的采集,后者常用于静态图片数据的采集,本文重点讨论内存映射方式的视频采集。

应用程序通过V4L2接口采集视频数据分为五个步骤:

首先,打开视频设备文件,进行视频采集的参数初始化,通过V4L2接口设置视频图像的采集窗口、采集的点阵大小和格式;

其次,申请若干视频采集的帧缓冲区,并将这些帧缓冲区从内核空间映射到用户空间,便于应用程序读取/处理视频数据;

第三,将申请到的帧缓冲区在视频采集输入队列排队,并启动视频采集;

第四,驱动开始视频数据的采集,应用程序从视频采集输出队列取出帧缓冲区,处理完后,将帧缓冲区重新放入视频采集输入队列,循环往复采集连续的视频数据;

第五,停止视频采集。

具体的程序实现流程可以参考下面的流程图:

关于usb接口的相机和MIPI接口的相机之间还有一个需要注意的区别是如下的类型:

/*	Stream type-dependent parameters
 */
struct v4l2_streamparm {
	__u32	 type;			/* enum v4l2_buf_type */
	union {
		struct v4l2_captureparm	capture;
		struct v4l2_outputparm	output;
		__u8	raw_data[200];  /* user-defined */
	} parm;
};

结构体包含两个结构体, 但是需要注意的v4l2_captureparm只能用于CAPTURE type, 而mipi接口的摄像头是不具有这种操作性的,即capability中没有这项

其对应的相关调用如下:

函数:ioctl(fd,VIDIOC_G_PARM,struct v4l2_streamparm *argp);  //VIDIOC_S_PARM

作用:流相关 (如帧率)

如有疑问,欢迎交流: wx:

baobaohaha_ 欢迎对SLAM有兴趣的小伙伴一起交流学习~~

参考:


V4L2对应的函数和变量详解


V4L2和MIPI接口的简要说明


V4L2学习流程分析


V4L2基础编程


V4L2官网讲解

英文


V4L2下摄像头的详细参数调整



版权声明:本文为qq_25458977原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。