2016-09-19 19 views
0

我使用gstreamer通过RTP发送H.264字节流。如何使rtpjitterbuffer在没有时间戳的流上工作?

# 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元素添加了正确的时间戳,但只是错误的数字。

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

+0

随着身份元素的到位,您是否尝试“调整”抖动缓冲区上的“延迟”? –

回答

1

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

如果我有一个MP4文件替换.h264文件,播放的伟大工程。

我假设我的h264流没有所需的时间戳来启用抖动缓冲器的功能。因为您使用的是原料 h264码流,而你确实应该使用具有这种信息的容器格式(例如,MP4)

您发送管道有没有协商的帧速率。没有时间戳udpsink无法与时钟同步,因此发送方正在以与管道可以处理它们一样快的速度分发数据包。这不是一个现场接收器。

但是,添加rtpjitterbuffer会使您的接收器充当直播来源。它冻结了,因为它正在尽最大努力应付格式错误的时间戳数据包。就我所知,RTP不会传输“缺失”时间戳,因此所有数据包都可能具有相同的时间戳。因此它可能会重建第一帧并将其余的重复放置为重复。

我必须同意user1998586从这个意义上说,它应该是更好的管道崩溃与一个好的错误消息,在这种情况下,而不是尽力而为。

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

你真的应该使用一个容器。

然而,理论上,一个au对齐的H264流可以加上时间戳,但没有gstreamer元素(我知道)这样做。

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 ! ... 
+0

在发送者流水线中使用“标识”元素,mode = 0使播放器更加灵活。调整数据速率没有帮助。 没有“身份”元素,mode = 0没有效果:接收器流水线在第一帧仍然冻结。 – matt

0

我有同样的问题,我找到了最好的解决办法将时间戳添加到发件人端的流中,将do-timestamp=1添加到源文件中。

没有时间戳,我不能让rtpjitterbuffer通过多个帧,不管我给了它什么选择。

(我正在处理的情况是从raspvid通过fdsrc流,我认为filesrc行为类似)。

gstreamer很容易发送gstreamer本身(和其他工具)无法正确处理的流:但如果没有时间戳有效,那么rtpjitterbuffer应该能够应付它;如果没有时间戳是无效的,那么rtph264pay应拒绝发送没有时间戳。我想这从来就不是一个用户界面...