我使用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"来自动生成发件人的时间戳。在某个地方正确上限?到目前为止,我的尝试都没有奏效。
答案 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
应该拒绝在没有时间戳的情况下发送。我想它从来没有打算作为用户界面......