我有一个自定义管道,在 gstreamer 速记中大致如下所示:
gst-launch-1.0 rtspsrc location=rtsp://<url-for-stream> ! rtph264depay ! h264parse ! imxvpudec ! *any-sink*
- any-sink 无关紧要,可以是 fakesink、imxipusink 或其他任何东西(我在使用飞思卡尔 imx 插件的 imx6 平台上)。我可以输出到我想要的任何接收器,问题是一样的。
这种类型的管道在 gst-launch-1.0 中运行良好,因为它不需要正确清理自己,但我需要使用直接 GST API 在我的 C++ 应用程序中使用它。这意味着我使用myPipeline = gst_pipeline_new("custom-pipeline")
,然后按名称分配每个插件,链接它们,然后运行管道。我后来需要停止管道并调用gst_object_unref(myPipeline)
. 这样做时,我观察到文件描述符被遗忘了。后来我需要重新启动管道,因此泄漏正在加剧。这需要经常发生,以至于泄漏的描述符给了我一个例外:
GLib-ERROR **: Creating pipes for GWakeup: Too many open files
lsof
我可以用...分析打开的文件
lsof +E -aUc myGstApplication
lsof: netlink UNIX socket msg peer info error
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
myGstApplication 5943 root 3u unix 0xabfb6c00 0t0 11200335 type=STREAM
myGstApplication 5943 root 11u unix 0xd9d47180 0t0 11207020 type=STREAM
......更多,取决于它运行多长时间......
myGstApplication 5943 root 50u unix 0xabe99080 0t0 11211987 type=STREAM
每次我 unref() 并重建管道时,我似乎都会得到两个新的 'type=STREAM' 文件描述符。
看到 lsof 中的描述符这一切都很好,而且很花哨,但我不知道如何在代码中追踪这些文件的来源。例如,是否有任何 lsof 输出实际上会引导我获得更好的调试信息?. 我如何追踪这些泄漏的真正来源并阻止它们?有更好的方法……对吧?
我怀疑rtspsrc
gstreamer 管道元素与此有关,但 rtspsrc 本身就是底层 gstreamer 实现(udpsrcs、demuxers 等)的泥潭。我不相信这是 rtspsrc 中的错误,因为还有很多其他人似乎使用这个而不复制相同的东西。我可以在我的应用程序代码中做一些可以以不明显的方式导致这种行为的东西吗?
非常感谢任何帮助,谢谢!