如何使rtpjitterbuffer在没有时间戳的流上工作?

时间:2016-09-19 04:06:10

标签: gstreamer rtp gstreamer-1.0

我使用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

然而,一旦我这样做,接收器只显示一个帧并冻结。

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

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

我添加identity datarate=1000000略有进步。这允许抖动缓冲器播放,但是这与我的帧速率有关,因为P帧的数据少于I帧。显然,identity元素添加了正确的时间戳,但只是添加了错误的数字。

是否可以通过指定" framerate"来自动生成发件人的时间戳。在某个地方正确上限?到目前为止,我的尝试都没有奏效。

3 个答案:

答案 0 :(得分:4)

您已经部分回答了问题:

  

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

     

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

您的发件人渠道没有协商的帧速率,因为您正在使用原始 h264流,而您应该使用具有此信息的容器格式(例如,MP4)。如果没有时间戳udpsink无法与时钟同步,那么发送方就像管道可以处理它们一样快速地吐出数据包。它不是 live 接收器。

但是,添加rtpjitterbuffer会使您的接收者充当直播来源。它冻结了,因为它正在尽最大努力应对大量错误时间戳的数据包。 RTP没有传输"丢失"据我所知,时间戳,所以所有数据包可能会有相同的时间戳。因此,它可能会重建第一帧,并将其余帧作为重复帧。

我必须同意 user1998586 ,因为在这种情况下管道应该更好地使用错误消息崩溃,而不是尽力而为。

  

是否可以通过指定" framerate"来自动生成发件人的时间戳。在某个地方正确上限?到目前为止,我的尝试都没有奏效。

没有。你应该真的使用容器。

然而,理论上,au对齐的H264原始流可以通过仅知道帧速率来加时间戳,但是没有gstreamer元素(我知道)这样做并且仅指定已赢得的封顶。做到了。

答案 1 :(得分: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 ! ...

答案 2 :(得分:0)

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

如果没有时间戳,我无法让rtpjitterbuffer传递多个帧,无论我给出了什么选项。

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

gstreamer很容易发送gstreamer本身(和其他工具)无法正确处理的流:如果没有时间戳有效,那么rtpjitterbuffer应该应对它;如果没有时间戳无效,那么rtph264pay应该拒绝在没有时间戳的情况下发送。我想它从来没有打算作为用户界面......