小编g3l*_*lux的帖子

使用 mmap 环形缓冲区捕获 v4l2 相机是否对跟踪应用程序有意义

我正在开发一个 v4l2 API,用于从嵌入式平台上的原始传感器捕获图像。我的捕获例程与[1]上的示例有关。建议的流式传输方法是使用 mmaped 缓冲区作为环形缓冲区。
对于初始化,使用带有 VIDIOC_REQBUFS 标识符的 ioctl 请求缓冲区(默认 = 4 个缓冲区)。随后,它们使用 VIDIOC_QBUF 排队。此处描述了整个流式传输过程[2]。一旦流开始,驱动程序就会用数据填充排队的缓冲区。v4l2_buffer 结构的时间戳表示捕获的第一个字节的时间,在我的情况下,这导致缓冲区之间的时间间隔约为 8.3 ms (=120fps)。到现在为止还挺好。
现在我对环形缓冲区的期望是新捕获以循环方式自动覆盖旧捕获。但事实并非如此。只有当缓冲区在出队 (VIDIOC_DQBUF) 和处理(去马赛克、跟踪步骤等)后再次排队 (VIDIOC_QBUF) 时,才会将新帧分配给缓冲区。如果我确实满足时序条件(处理 < 8.3 ms),则出队时我不会得到最新捕获的帧,而是最旧的捕获帧(根据 FIFO),因此是当前帧之前 3x8.3 ms 的帧。如果不满足时序条件,则时间跨度会变得更大,因为缓冲区不会被覆盖。

所以我有几个问题:
1. 这个跟踪应用程序有一个环形缓冲区是否有意义,因为我真的不需要帧的历史记录?我当然对此表示怀疑,但是通过使用建议的 mmap 方法,驱动程序通常需要请求最少数量的缓冲区。
2. 一个单独的线程是否应该连续使用 DQBUF 和 QBUF 来完成缓冲区覆盖?这怎么可能实现?
3. 作为一种解决方法,您可能会在每次捕获时使所有缓冲区出队和重新入队,但这听起来不对。是否有人在实时捕获和流式传输方面具有更多经验,可以指出“正确”的方法?
4. 目前,我正在 DQBUF 和 QBUF 之间进行预处理步骤(去马赛克)以及之后的跟踪步骤。在再次调用 QBUF 之前是否也应该执行跟踪步骤?

所以主要代码基本上是在一个while循环中依次执行Capture()和Track()。Capture 例程如下所示:

cv::Mat v4l2Camera::Capture( size_t timeout ) { 

    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(mFD, &fds);

    struct timeval tv;

    tv.tv_sec  = 0;
    tv.tv_usec = 0;

    const bool …
Run Code Online (Sandbox Code Playgroud)

c++ video-capture v4l2

5
推荐指数
0
解决办法
809
查看次数

标签 统计

c++ ×1

v4l2 ×1

video-capture ×1