我正在开发一个GStreamer应用程序,并为实现传入RTP流的播放器而苦苦挣扎.我正在尝试围绕gstrtpbin元素构建一个管道.我正在尝试使用gst-launch构造对管道进行建模:
VIDEO_CAPS="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264" gst-launch -v udpsrc caps=$VIDEO_CAPS port=4444 \ ! gstrtpbin .recv_rtp_sink_0 \ ! rtph264depay ! ffdec_h264 ! xvimagesink
当我启动脚本时,GStreamer报告这些错误:
Setting pipeline to PAUSED ... Pipeline is live and does not need PREROLL ... Setting pipeline to PLAYING ... /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpSession:rtpsession0: ntp-ns-base = 3469468914024449000 New clock: GstSystemClock /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpSession:rtpsession0.GstPad:recv_rtp_sink: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264 /GstPipeline:pipeline0/GstRtpBin:rtpbin0.GstGhostPad:recv_rtp_sink_0: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264 /GstPipeline:pipeline0/GstRtpBin:rtpbin0.GstGhostPad:recv_rtp_sink_0.GstProxyPad:proxypad0: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264 /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpSession:rtpsession0.GstPad:recv_rtp_src: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264 /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpSsrcDemux:rtpssrcdemux0.GstPad:sink: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264 /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpJitterBuffer:rtpjitterbuffer0.GstPad:src: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264 /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpJitterBuffer:rtpjitterbuffer0.GstPad:sink: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264 /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpPtDemux:rtpptdemux0.GstPad:sink: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264 /GstPipeline:pipeline0/GstRtpBin:rtpbin0.GstGhostPad:recv_rtp_src_0_960476599_33.GstProxyPad:proxypad1: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)33 ERROR: from element /GstPipeline:pipeline0/GstUDPSrc:udpsrc0: Internal data flow error. Additional debug info: gstbasesrc.c(2378): gst_base_src_loop (): /GstPipeline:pipeline0/GstUDPSrc:udpsrc0: streaming task paused, reason not-linked (-1) Execution ended after 209381685 ns. Setting pipeline to PAUSED ... Setting pipeline to READY ... /GstPipeline:pipeline0/GstRtpBin:rtpbin0.GstGhostPad:recv_rtp_src_0_960476599_33: caps = NULL /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpPtDemux:rtpptdemux0.GstPad:src_33: caps = NULL /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpPtDemux:rtpptdemux0.GstPad:sink: caps = NULL /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpJitterBuffer:rtpjitterbuffer0.GstPad:sink: caps = NULL /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpJitterBuffer:rtpjitterbuffer0.GstPad:src: caps = NULL /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpSsrcDemux:rtpssrcdemux0.GstPad:src_960476599: caps = NULL /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpSsrcDemux:rtpssrcdemux0.GstPad:sink: caps = NULL /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpSession:rtpsession0.GstPad:recv_rtp_src: caps = NULL /GstPipeline:pipeline0/GstRtpBin:rtpbin0/GstRtpSession:rtpsession0.GstPad:recv_rtp_sink: caps = NULL /GstPipeline:pipeline0/GstRtpBin:rtpbin0.GstGhostPad:recv_rtp_sink_0: caps = NULL /GstPipeline:pipeline0/GstUDPSrc:udpsrc0.GstPad:src: caps = NULL Setting pipeline to NULL ... Freeing pipeline ...
我应该提到它适用于playbin和SDP文件.例如这个文件:
v=0 o=- 1188340656180883 1 IN IP4 127.0.0.1 s=Session streamed by GStreamer i=server.sh t=0 0 a=tool:GStreamer a=type:broadcast m=video 4444 RTP/AVP 96 c=IN IP4 127.0.0.1 a=rtpmap:96 H264/90000
可以像这样播放流:
gst-launch -vvv playbin uri=file://`pwd`/stream.sdp
为了完整性:我使用VLC发送数据.这是命令:
vlc -I rc /usr/local/movies/sample.mp4 \ --screen-fps=10 :screen-caching=100 \ --sout='#transcode{vcodec=h264,venc=x264{bframes=0,keyint=40},vb=512}:\ rtp{mux=ts,dst=127.0.0.1,port=4444}'
有人会帮我理解gst-launch脚本失败的原因吗?错误"原因未链接"让我认为gstrtpbin和rtph264depay元素之间的链接被破坏了.但我不知道如何解决它.
编辑
遵循RAOF的建议我在我的命令中修复了一些错误.但是我使用的是ffdec_h264和autovideosink,因为在我的Windows系统上我没有安装fluh264dec和xvimage sink插件:
gst-launch-0.10 udpsrc port=4444 caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264" ! .recv_rtp_sink_0 gstrtpbin ! rtpmp2tdepay ! mpegtsdemux ! ffdec_h264 ! autovideosink
这会导致新的错误:
0:00:00.743000000 516 024070A8 ERROR ffmpeg .:0:: non-existing PPS referenced 0:00:00.744000000 516 024070A8 ERROR ffmpeg .:0:: non-existing PPS referenced 0:00:00.745000000 516 024070A8 ERROR ffmpeg .:0:: decode_slice_header error 0:00:00.745000000 516 024070A8 ERROR ffmpeg .:0:: no frame! 0:00:00.812000000 516 024070A8 ERROR ffmpeg .:0:: non-existing PPS referenced 0:00:00.813000000 516 024070A8 ERROR ffmpeg .:0:: non-existi ... ERROR: from element /GstPipeline:pipeline0/GstUDPSrc:udpsrc0: Internal data flow error. Additional debug info: ..\Source\gstreamer\libs\gst\base\gstbasesrc.c(2378): gst_base_src_loop (): /Gst Pipeline:pipeline0/GstUDPSrc:udpsrc0: streaming task paused, reason not-negotiated (-4) Execution ended after 4790000000 ns. Setting pipeline to PAUSED ... Setting pipeline to READY ... Setting pipeline to NULL ... Freeing pipeline ...
我还在试图弄清楚如何解决这个问题.如果您能提供帮助,请随时这样做.
Edit2
我使用SDP解决方案再次测试并观察到"不存在的PPS"错误也会发生,但视频确实会播放.另一方面,致命的"内部数据流错误"仅在使用自定义管道解决方案时显示.我怀疑"不存在的PPS"错误是由x264编码器引起的."内部数据流错误"必须由我的管道中的错误引起,或者某些Windows插件中的错误.我会进一步研究......
据我所知,你有两个问题:
首先,似乎接收器规范的顺序很重要:而不是... ! gstrtpbin .recv_rtp_sink_0 ! ...
你需要的... ! .recv_rtp_sink_0 gstrtpbin ! ...
.
其次,vlc正在发送一个MPEG2传输流 - 你已经获得mux=ts
了rtp流输出描述符 - 但是你正试图降低原始h264流的负载.您需要对ts流进行depayload,然后对其进行解复用以获取h264流数据.
所以,最后,管道
gst-launch-0.10 -v udpsrc port=4444 \ caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264" \ ! .recv_rtp_sink_0 gstrtpbin ! rtpmp2tdepay \ ! mpegtsdemux ! fluh264dec ! xvimagesink
适用于我,使用TS demuxer(mpegtsdemux)和h264解码器(fluh264dec).