我正在开发一个 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 插件中的错误。我会做一些进一步的研究...