我不知道为此目的有一个好的库(请添加评论并告诉我是否有一个:-))。注意:对于某些用途,例如。 OpenCV 很好,if it is enough for you, definitely do use it。但如果您想了解更多,请继续阅读。
所以你应该只写你自己的代码来使用它,这并不是特别难。这是一个相关的问题:How to use/learn Video4Linux2 (On Screen Display) Output APIs?
让学习更容易的几点:
调用 IOCTL 后,始终检查返回状态并打印可能的错误消息。在你工作的时候你会得到很多这样的东西,所以要系统地处理它。我建议使用如下所示的 check_error 之类的函数,并且总是在任何 ioctl 调用之后立即调用它。
IMO 必须:使用 IDE/编辑器,它可以跟随符号到实际的头文件(例如在 Qt Creator 中,它是一个很好的纯 C 应用程序 IDE,尽管名称如此,在符号上按 F2,它甚至会转到系统标题以向您显示它的定义位置)。在 V4L2 相关的符号和定义上大量使用它,并在头文件中读取 cmets,这通常是最好的文档。
使用查询 ioctls 和编写函数来转储它们以良好格式返回的值。例如,有函数void dump_cap(const struct v4l2_capability &cap) {...},并为您在代码中使用的每个结构添加一个类似的函数。
不要懒于在传递给 IOCTL 的结构中设置值。在声明它们之后,总是使用memset(&ioctl_struct_var, 0, sizeof(ioctl_struct_var)); 将结构初始化为 0,并且如果你重用它们(除非对某些设置执行“get-modify-set”操作,这在 V4L2 中很常见)。
如果可能,请使用两个(或更多)不同的网络摄像头(不同的分辨率、不同的品牌),并使用两个(全部)进行测试。如果您将视频设备作为命令行参数,这是最简单的,因此您可以为您拥有的每个摄像头使用不同的参数调用您的程序。
小步骤。通常 ioctls 可能不会返回您期望的结果,因此在您真正看到查询为您的相机返回的内容之前,没有必要编写使用返回数据的代码。
上面提到的check_error函数:
void check_error(int return_value_of_ioctl, const char *msg) {
if (return_value_of_ioctl != -1) return; /* all ok */
int eno = errno; /* just to avoid accidental clobbering of errno */
fprintf(stderr, "error (%d) with %s: %s\n", eno, msg, strerror(eno));
exit(1); /* optional, depending on how you want to work with your code */
}
在每个 ioctl 之后立即调用它,例如:
struct v4l2_capability cap;
setmem(&cap, 0, sizeof(cap));
int r=ioctl(fd, VIDIOC_QUERYCAP, &cap);
check_error(r, "VIDIOC_QUERYCAP");
dump_querycap(&cap);