我有一个科学应用程序,可以捕获 video4Linux 视频流。捕捉每一帧并且不丢失任何人是至关重要的。不幸的是,框架到处都不见了,我不知道为什么。
为了检测丢帧,我在读取帧后直接将 v4l2_buffer 的序列号与我自己的计数器进行比较:
void detectDroppedFrame(v4l2_buffer* buffer) {
_frameCounter++;
auto isLastFrame = buffer->sequence == 0 && _frameCounter > 1;
if (!isLastFrame && _frameCounter != buffer->sequence+1)
{
std::cout << "\n####### WARNING! Missing frame detected!" << std::endl;
_frameCounter = buffer->sequence+1; // re-sync our counter with correct frame number from driver.
}
}
Run Code Online (Sandbox Code Playgroud)
我的运行 1 文件示例要点可以在 github 上找到(基于官方 V4L2 捕获示例):https://gist.github.com/SebastianMartens/7d63f8300a0bcf0c7072a674b3ea4817
在笔记本硬件(uvcvideo 驱动程序)上的 Ubuntu 18.04 虚拟机上使用网络摄像头进行了测试,并在本地运行 ubuntu 18.04 的嵌入式硬件上使用 CSI 摄像头进行了测试。帧未处理,缓冲区似乎被足够快地抓取(使用 VIDIOC_QUERYBUF 检查缓冲区状态,这表明所有缓冲区都在驱动程序的传入队列中,并且未设置 V4L2_BUF_FLAG_DONE 标志)。我使用 MMAP 以及 UserPtr 方法丢失了帧。而且它似乎与像素格式、图像大小和帧速率无关!
对我来说,如果相机/v4l2驱动程序无法足够快地填充可用缓冲区,但使用VIDIOC_S_PRIORITY命令增加文件描述符优先级也没有帮助(仍然可能是线程调度问题?)。
=> …