CPU 如何在没有完全解码的情况下从 h264 中提取运动矢量

How to extract motion vectors from h264 without a full decode on the CPU

我正在尝试将我的鼻子用作指示设备。计划是将来自指向我脸部的网络摄像头的视频流编码为 h264 或类似格式,获取运动矢量,稍微处理数字并将它们放入 /dev/uinput 中,使鼠标指针移动。 uinput 位很简单。

这必须在零可辨别的延迟下工作。例如:

#!/bin/bash
[ -p pipe.mkv ] || mkfifo pipe.mkv
ffmpeg -y -rtbufsize 1M -s 640x360 -vcodec mjpeg -i /dev/video0 -c h264_nvenc pipe.mkv &
ffplay -flags2 +export_mvs -vf codecview=mv=pf+bf+bb pipe.mkv

表明向量在那里,但有几秒钟的延迟,这在鼠标中是不可用的。我知道第一个 ffmpeg 步骤通过使用 GPU 工作得非常快,所以第二步中的管道或 h264 解码会引入延迟。

我在类似的管道布置中尝试了 MV Tractus(我认为与 mpegflow 相同),它也非常慢。他们在 CPU 上进行了完整的 h264 解码,我认为这是问题所在,因为我可以看到他们在一个 CPU 上施加了很多负载。如果管道因缓冲不良而导致延迟,则 CPU 不会被加载。我猜 ffplay 也在 CPU 上进行了解码,我无法说服它不这样做,但它只想画对我没有用的箭头。

我认为有几种方法,我想知道哪种方法最好,或者是否还有我不知道的更好的方法。我可以:

我倾向于第二个选项,但我需要一些帮助来确定在 libav 代码中的哪个位置执行此操作。

非常有趣的项目!我不是 ffmpeg 专家,但在我看来,您的 ffmpeg 命令正在解码 /dev/video0 的 mjpeg 输出,然后将其编码为 h.264 以获得运动矢量。 h.264 编码步骤是计算密集型的,可能会导致您的延迟。您可以做一些事情来加快速度:(a)使用输出 h.264 而不是 mjpeg 的网络摄像头; (b) 运行 在更快的硬件上进行 h.264 编码和 (c) 在编码之前使用 ffmpeg 降低视频流的分辨率。例如,您可以在摄像机中定义一个小的“热区”,您的鼻子的运动可以在其中控制鼠标。