我开发了一个自定义 GStreamer 组件
infer
,它运行神经网络模型。该组件大约需要 100 毫秒来处理每一帧,从而导致预期帧速率约为 10 fps。然而,我面临一个问题,管道报告丢失帧,导致有效帧速率约为 1 fps。错误信息是:
0:00:47.405558285 4623 0xaaab095005e0 WARN v4l2src gstv4l2src.c:1352:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 21 - ts: 0:00:46.169338790
这是我正在使用的管道配置:
webrtcbin bundle-policy=max-bundle latency=0 name=sendrecv \
v4l2src ! capsfilter caps="video/x-raw, width=1920, height=1080, framerate=25/1" ! videoconvert ! infer use_npu=True type=yolov5 model=yolov5n.tflite labels=yolov5n.txt ! videoconvert ! queue max-size-buffers=1 ! x264enc bitrate=5000 speed-preset=superfast tune=zerolatency ! video/x-h264, stream-format=byte-stream ! rtph264pay config-interval=1 ! application/x-rtp,media=video,encoding-name=H264,payload=127 ! sendrecv.
我怀疑帧处理速度太慢,导致积压,导致帧丢失。如果
infer
元素仍然忙于先前的帧处理,我想在它们处理之前丢弃帧。我怎样才能实现这个目标?或者还有其他解决办法吗?
附注我在收到消息
GST_MESSAGE_LATENCY
时执行“gst_bin_recalculate_latency”并将管道延迟设置为 250。但这没有帮助。
要从队列中删除帧,您可以设置队列的 leaky 属性。
默认情况下,其设置为
leaky=0
- 不会丢帧。
设置
leaky=1
或 leaky=upstream
删除新帧
设置
leaky=2
或 leaky=downstream
删除旧帧
现在,在您的管道中,您已在
queue
元素之后添加了 infer
。如果您想删除 infer
之前的帧,请在其前面添加 queue max-size-buffers=1 leaky=downstream
。
此外,
x264enc
是繁重的处理元素,但您可能不需要在此元素之前丢弃帧,并且可以在此之前删除队列上的最大大小缓冲区限制。
所以管道看起来像这样
webrtcbin bundle-policy=max-bundle latency=0 name=sendrecv \
v4l2src ! capsfilter caps="video/x-raw, width=1920, height=1080, framerate=25/1" ! videoconvert ! queue max-size-buffers=1 leaky=downstream ! infer use_npu=True type=yolov5 model=yolov5n.tflite labels=yolov5n.txt ! videoconvert ! queue ! x264enc bitrate=5000 speed-preset=superfast tune=zerolatency ! video/x-h264, stream-format=byte-stream ! rtph264pay config-interval=1 ! application/x-rtp,media=video,encoding-name=H264,payload=127 ! sendrecv.