使用“时钟时间”而不是 GStreamer 管道的运行时间

问题描述 投票:0回答:2

我有两个 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 秒后,我停止“源”管道,然后重新启动管道,运行时间将重置为零,导致发送的所有缓冲区的时间戳被接收器管道视为旧缓冲区,因为它已经收到时间戳 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),如该页面上的图像。

我已经看过这篇文章,并在我的视频源上尝试了

is-live
do-timestamp
,但它们似乎没有达到我想要的效果。我还尝试根据系统时间手动设置缓冲区中的时间戳(DTS、PTS),但无济于事。

有什么建议吗?

gstreamer pts
2个回答
1
投票

GstBaseSrc 有

do-timestamp
属性,它完全可以满足您的需求。当您设置
do-timestamp=true
时,大多数实时源将使用时钟时间为缓冲区添加时间戳(如果它们遵守的话)。

这是来自 Aravis 的示例: https://github.com/AravisProject/aravis/commit/d1cbf643e5251d26199d799d98b8d05d1ad255a7

这是我正在谈论的属性: https://gstreamer.freedesktop.org/documentation/base/gstbasesrc.html?gi-language=c#GstBaseSrc:do-timestamp


0
投票

我认为你也应该重新启动接收器管道。您可以将

-e
开关添加到发送方管道,当您停止管道时,它应该通过 GDP 元素将 EOS 正确传播到接收方管道。否则我想你可以向接收者发送一个新的段或不连续性。但必须发出某些事件信号才能使管道意识到该变化,否则它就是有点虚假的数据。我想说重新启动接收器是最简单的方法。

© www.soinside.com 2019 - 2024. All rights reserved.