4

我正在使用 gstreamer 通过 RTP 发送 H.264 字节流。

# sender
gst-launch-1.0 filesrc location=my_stream.h264 ! h264parse disable-passthrough=true ! rtph264pay config-interval=10 pt=96 ! udpsink host=localhost port=5004

然后我在其他 gstreamer 实例中接收帧、解码和显示。

# receiver
gst-launch-1.0 udpsrc port=5004 ! application/x-rtp,payload=96,media="video",encoding-name="H264",clock-rate="90000" ! rtph264depay ! h264parse ! decodebin ! xvimagesink

这按原样工作,但我想尝试添加一个 rtpjitterbuffer 以完美平滑播放。

# receiver
gst-launch-1.0 udpsrc port=5004 ! application/x-rtp,payload=96,media="video",encoding-name="H264",clock-rate="90000" ! rtpjitterbuffer ! rtph264depay ! h264parse ! decodebin ! xvimagesink

但是,一旦我这样做,接收器只会显示一个帧并冻结。

如果我用 MP4 文件替换 .h264 文件,播放效果很好。

我假设我的 h264 流没有启用抖动缓冲区所需的时间戳。

我通过添加identity datarate=1000000. 这允许 jitterbuffer 播放,但是这与我的帧速率有关,因为 P 帧的数据比 I 帧少。显然,该identity元素添加了正确的时间戳,但只是使用了错误的数字。

是否可以通过在某处正确指定“帧率”上限来自动在发件人上生成时间戳?到目前为止,我的尝试没有奏效。

4

3 回答 3

5

您已经部分回答了这个问题:

如果我用 MP4 文件替换 .h264 文件,播放效果很好。

我假设我的 h264 流没有启用抖动缓冲区所需的时间戳。

您的发送方管道没有协商的帧速率,因为您使用的是原始h264 流,而您实际上应该使用包含此信息的容器格式(例如 MP4)。如果没有时间戳udpsink,则无法与时钟同步以进行节流,因此发送方以管道可以处理它们的速度吐出数据包。这不是一个水槽。

但是添加 artpjitterbuffer会使您的接收器充当实时源。它之所以冻结,是因为它正在尽最大努力应对大量格式错误的时间戳数据包。据我所知,RTP 不会传输“丢失”的时间戳,因此所有数据包都可能具有相同的时间戳。因此,它可能会重建第一帧并将其余帧作为重复帧丢弃。

我必须同意user1998586的观点,在这种情况下,最好让管道崩溃并显示一个好的错误消息,而不是尽力而为。

是否可以通过在某处正确指定“帧率”上限来自动在发件人上生成时间戳?到目前为止,我的尝试没有奏效。

不,你真的应该使用容器。

然而,理论上,一个au对齐的 H264 原始流可以通过只知道帧速率来加时间戳,但是没有 gstreamer 元素(我知道)可以做到这一点,仅仅指定 caps 不会做到这一点。

于 2017-04-19T10:54:31.587 回答
1

我遇到了同样的问题,我找到的最佳解决方案是通过添加do-timestamp=1到源中,将时间戳添加到发送方的流中。

如果没有时间戳,无论我给出什么选项,我都无法rtpjitterbuffer通过超过一帧。

(我正在处理的案例是从raspvidvia流式传输的fdsrc,我认为filesrc行为类似)。

gstreamer 如此轻松地发送 gstreamer 本身(和其他工具)无法正确处理的流确实有点糟糕:如果没有时间戳是有效的,那么rtpjitterbuffer应该处理它;如果没有时间戳是无效的,那么rtph264pay应该拒绝发送没有时间戳。我想它从来没有打算作为用户界面......

于 2017-01-10T08:24:50.813 回答
0

您应该尝试将rtpjitterbuffer模式设置为默认值以外的其他值:

mode                : Control the buffering algorithm in use
                        flags: readable, writable
                        Enum "RTPJitterBufferMode" Default: 1, "slave"
                           (0): none             - Only use RTP timestamps
                           (1): slave            - Slave receiver to sender clock
                           (2): buffer           - Do low/high watermark buffering
                           (4): synced           - Synchronized sender and receiver clocks

像那样:

... ! rtpjittrbuffer mode=0 ! ...
于 2016-09-22T17:09:29.740 回答