>我有一个自定义管道,在gstreamer速记中大致如下所示:
gst-launch-1.0 rtspsrc location=rtsp://<url-for-stream> ! rtph264depay ! h264parse ! imxvpudec ! *any-sink*
- 任何sink都无关紧要,可能是fakesink,imxipusink或其他任何东西(我在imx6平台上使用飞思卡尔imx插件(。我可以输出到我想要的任何接收器,问题是一样的。
这种类型的管道在 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
每次我取消引用((并重建管道时,我似乎都会得到两个新的"type=STREAM"文件描述符。
在 lsof 中看到描述符都很好,但我不知道如何在代码中追踪这些文件的来源。例如,是否有任何 lsof 输出实际上引导我更好地调试信息?.我如何追踪这些泄漏的真正来源并阻止它们?有更好的方法...右?
我怀疑 gstreamer 管道元素与此有关rtspsrc
但 rtspsrc 本身就是底层 gstreamer 实现(udpsrcs、解复用器等(的泥沼。我不相信这是 rtspsrc 中的一个错误,因为许多其他人似乎在没有复制相同内容的情况下使用这个错误。我可以在我的应用程序代码中做一些事情,以一种不明显的方式带来这种行为吗?
非常感谢任何帮助,谢谢!
经过充分研究和有趣的问题!
根据 lsof 输出,泄漏的文件描述符似乎源自套接字对系统调用。 您可以使用 strace 确认这一点:
strace -fe socketpair myGstApplication
在此之后,您可以省略套接字对 sycall 的过滤,并查看完整的 strace 输出,尝试了解这些 FD 的用途。 我用 gst-launch-1.0 尝试过这个,结果不确定。 这些 FD 似乎在两端都设置为只读,并且不会传输任何内容......因此,它们必须仅用于同一应用程序的多个线程/子进程之间的控制/协调。
下一次尝试将是 gdb:
gdb -ex 'break socketpair' -ex run myGstApplication
当它在断点处停止时,使用bt命令查看堆栈跟踪。 可能安装 gstreamer 的调试包是一个好主意,以获得更具可读性的堆栈跟踪。
HTH :)