【发布时间】:2021-11-25 22:28:08
【问题描述】:
我有两个 GStreamer 管道,一个就像一个“源”管道,将实时摄像头馈送到外部通道,第二个管道就像一个“接收器”管道,从该通道的另一端读取并输出将实时视频传输到某种形式的接收器。
[videotestsrc] -> [appsink] ----- Serial Channel ------> [appsrc] -> [autovideosink]
First Pipeline Second Pipeline
第一个管道从 videotestsrc 开始,对视频进行编码并将其包装在 gdppay 有效负载中,然后将管道接收到串行通道中(但为了问题起见,任何可以从中读取的接收器启动另一个管道,例如写入串行端口或 udpsink 的文件接收器),它由下一个管道的源读取并通过 autovideosrc 显示:
“源”管道
gst-launch-1.0 -v videotestsrc ! videoconvert ! video/x-raw,format=I420 ! x265enc ! gdppay ! udpsink host=127.0.0.1 port=5004
“汇”管道
gst-launch-1.0 -v udpsrc uri=udp://127.0.0.1:5004 ! gdpdepay ! h265parse ! avdec_h265 ! autovideosink
注意:鉴于使用 udpsink/udpsrc 引起的延迟,该管道会抱怨时间戳问题。如果您将 udpsrc/udpsink 替换为 filesrc/filesink 到串行端口,您可以看到我将要描述的问题。
问题:
现在我已经描述了管道,这里有问题: 如果我启动两个管道,一切都会按预期工作。但是,如果在 30 秒后,我停止“源”管道并重新启动管道,Running Time 将重置为零,导致所有缓冲区的时间戳被发送到接收器管道视为旧缓冲区,因为它有已经接收到时间戳为 0 到 30 秒的缓冲区,因此另一端的播放要到 30 秒后才会恢复:
Source Pipeline: [28][29][30][0 ][1 ][2 ][3 ]...[29][30][31]
Sink Pipeline: [28][29][30][30][30][30][30]...[30][30][31]
________________________^
Source pipeline restarted
^^^^^^^^^^^^^^^^...^^^^^^^^
Sink pipeline will continue
to only show the "frame"
received at 30s until a
"newer" frame is sent, when
in reality each sent frame
is newer and should be shown
immediately.
解决方案
我发现将sync=false 添加到autovideosink 确实可以解决问题,但是我希望找到一个解决方案,其中源将基于Clock time 发送其时间戳(DTS 和 PTS),如中所示该页面上的图像。
我已经看到this post 并在我的视频源上尝试了is-live 和do-timestamp,但它们似乎并没有达到我想要的效果。我还尝试根据系统时间手动设置缓冲区中的时间戳(DTS、PTS),但无济于事。
有什么建议吗?
【问题讨论】: