Gstreamer:在RTP流中暂停/恢复视频
我正在构建一个从网络源接收两个RTP流的gstreamer管道:
一切都放到一个gstreamer管线中,因此它将使用两个流中的RTCP来同步音频/视频。 到目前为止,我已经提出了这个问题(使用gst-launch进行原型设计):
gst-launch -vvv gstrtpbin name=rtpbin
udpsrc caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H263-2000" port=40000 ! rtpbin.recv_rtp_sink_0
rtpbin. ! rtph263pdepay ! ffdec_h263 ! xvimagesink
udpsrc port=40001 ! rtpbin.recv_rtcp_sink_0
rtpbin.send_rtcp_src_0 ! udpsink port=40002 sync=false async=false
udpsrc caps="application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)PCMU,encoding-params=(string)1,octet-align=(string)1" port=60000 rtpbin.recv_rtp_sink_1
rtpbin. ! rtppcmudepay ! autoaudiosink
udpsrc port=60001 ! rtpbin.recv_rtcp_sink_1
rtpbin.send_rtcp_src_1 ! udpsink port=60002 sync=false async=false
如果网络源开始发送视频和音频,则此管道工作良好。 如果视频流稍后暂停,gstreamer仍会播放音频,甚至会在网络源恢复视频流时开始播放视频。
然而,我的问题是,如果网络源只有一个音频流(视频可能稍后添加),流水线似乎暂停/冻结,直到视频流开始。
由于在我的应用程序中视频是可选的(并且可以随意添加/删除),是否有任何方法可以连接到例如'videotestsrc',它将提供某种回退视频数据以保持管道在运行时运行没有网络视频数据?
我尝试过试用'videotestsrc'和'videomixer'这个东西,但我认为混音器仍然需要两个流才能生存。 任何反馈非常感谢!
我提出了一个简单的函数,用于通过更改垃圾箱来暂停继续。 在下面的示例中,我提供了动态地更改目标箱的逻辑。 这不会完全阻止你所寻求的管道,我相信。 类似的逻辑可以用于src箱。 在这里你可以删除你的网络源bin和相关的解码器/ demux bin并添加videotestsrc bin。
private static void dynamic_bin_replacement(Pipeline pipe, Element src_bin, Element dst_bin_new, Element dst_bin_old) {
pipe.pause();
src_bin.unlink(dst_bin_old);
pipe.remove(dst_bin_old);
pipe.add(dst_bin_new);
dst_bin_new.syncStateWithParent();
src_bin.link(dst_bin_new);
pipe.ready();
pipe.play();
}
你可能想尝试的另一个逻辑是“PADLOCKING”。 请看看下面的帖子
http://cgit.freedesktop.org/gstreamer/gstreamer/tree/docs/design/part-block.txt
和
http://web.archiveorange.com/archive/v/8yxpz7FmOlGqxVYtkPb4
和
在移动过程中向/从GStreamer管道添加和删除音频源
UPDATE
尝试输出选择器和输入选择器,因为它们似乎是更好的选择。 我发现他们最可靠,并与他们有巨大的运气。 我分别使用fakesink或fakesrc作为选择器的另一端。
阀箱是另一种选择,我发现甚至不需要fakesink或fakesrc箱。 它也非常可靠。
也是媒体文件源的正确状态转换顺序
NULL - > READY - > PAUSED - > PLAYING(向上)
PLAYING - > PAUSED - > READY - > NULL(向下)
在ready()应该在pause()之前出现以上示例中的顺序应该更正。 我也倾向于认为un-linking应该在null()状态之后执行,而不是在pause()之后执行。 我没有尝试过这些改变,但理论上他们应该工作。
有关详细信息,请参阅以下链接
http://cgit.freedesktop.org/gstreamer/gstreamer/tree/docs/design/part-states.txt?h=BRANCH-RELEASE-0_10_19
链接地址: http://www.djcxy.com/p/60169.html