GStreamer RTSP Server RTP透传实现遇预滚失败问题求助
问题描述
需求
实现RTSP Server的透传功能:一个端点接收推送的RTP数据包,另一个端点允许客户端拉流观看这些数据包。
当前实现
推送命令
gst-launch-1.0 videotestsrc ! video/x-raw,width=640,height=480,format=I420,framerate=30/1,clock-rate=90000 ! x264enc ! h264parse ! rtspclientsink location=rtsp://localhost:8554/push protocols=tcp
Record模式Media Factory管道(接收推送)
self.set_launch("""rtph264depay name=depay0 ! queue ! intersink producer-name="rtp-source"""")
Pull模式Media Factory管道(提供拉流)
self.set_launch("""intersrc producer-name="rtp-source" ! h264parse ! rtph264pay pt=96 config-interval=5 name=pay0""")
工厂挂载逻辑(客户端连接回调)
def on_options_request(self, client, context): global routes print(client) print(context) if 'test' not in routes: print("test not in routes") push_factory = RecordMediaFactory() pull_factory = PlayMediaFactory() routes = {'test': {'push': None, 'pull': None}} routes['test']['push'] = push_factory routes['test']['pull'] = pull_factory self.get_mount_points().add_factory("/push", push_factory) self.get_mount_points().add_factory("/pull", pull_factory)
遇到的问题
拉流时preroll失败,服务器无法响应客户端的DESCRIBE请求,客户端提示“no media”和“can't get sdp”。服务器超时堆栈跟踪如下:
0:00:20.363756958 76394 0x600003645e00 DEBUG rtspstream rtsp-stream.c:4840:on_message_sent:<GstRTSPStream@0x13d70aad0> message send complete 0:00:20.363774000 76394 0x600003645e00 INFO rtspclient rtsp-client.c:2334:do_keepalive: keep session 0x600002044710 alive 0:00:23.701245291 76394 0x60000367c000 DEBUG rtspmedia rtsp-media.c:3133:gst_rtsp_media_get_status: timeout, assuming error status 0:00:23.701312083 76394 0x60000367c000 DEBUG rtspmedia rtsp-media.c:3139:gst_rtsp_media_get_status: got status 5 0:00:23.701325000 76394 0x60000367c000 WARN rtspmedia rtsp-media.c:3933:wait_preroll: failed to preroll pipeline 0:00:23.701330375 76394 0x60000367c000 WARN rtspmedia rtsp-media.c:4303:gst_rtsp_media_prepare: failed to preroll pipeline 0:00:23.701391208 76394 0x60000367c000 INFO rtspmedia rtsp-media.c:4446:gst_rtsp_media_unprepare: unprepare media 0x13d606460 0:00:23.701406041 76394 0x60000367c000 INFO rtspmedia rtsp-media.c:3469:set_target_state: set target state to NULL for media 0x13d606460 0:00:23.701416916 76394 0x60000367c000 DEBUG rtspmedia rtsp-media.c:3106:gst_rtsp_media_set_status: setting new status to 1 0:00:23.701509291 76394 0x60000367c000 DEBUG rtspmedia rtsp-media.c:4321:finish_unprepare: shutting down 0:00:23.701524208 76394 0x60000367c000 INFO rtspmedia rtsp-media.c:3456:set_state: set state to NULL for media 0x13d606460 0:00:23.701991291 76394 0x6000036401e0 DEBUG rtspmedia rtsp-media.c:3544:default_handle_message: 0x13d606460: went from PLAYING to PAUSED (pending NULL) 0:00:23.702419208 76394 0x60000367c000 DEBUG rtspmedia rtsp-media.c:3074:media_streams_set_blocked: media 0x13d606460 set blocked 0 0:00:23.702437000 76394 0x60000367c000 DEBUG rtspstream rtsp-stream.c:5523:set_blocked:<GstRTSPStream@0x13d607010> blocked: 0 0:00:23.702445333 76394 0x60000367c000 INFO rtspmedia rtsp-media.c:4334:finish_unprepare: Removing elements of stream 0 from pipeline 0:00:23.702451458 76394 0x60000367c000 INFO rtspstream rtsp-stream.c:4163:gst_rtsp_stream_leave_bin: stream 0x13d607010 leaving bin 0:00:23.702629125 76394 0x60000367c000 DEBUG rtspmedia rtsp-media.c:3106:gst_rtsp_media_set_status: setting new status to 0 0:00:23.703029083 76394 0x60000367c000 DEBUG rtspmedia rtsp-media.c:4377:finish_unprepare: removing bus watch 0:00:23.703042750 76394 0x60000367c000 DEBUG rtspmedia rtsp-media.c:3720:watch_destroyed:<GstRTSPMedia@0x13d606460> source destroyed 0:00:23.703051375 76394 0x60000367c000 DEBUG rtspmedia rtsp-media.c:4382:finish_unprepare: destroy source 0:00:23.703057541 76394 0x60000367c000 DEBUG rtspmedia rtsp-media.c:4388:finish_unprepare: stop thread 0:00:23.703070541 76394 0x60000367c000 ERROR rtspclient rtsp-client.c:1117:find_media: client 0x11d64a8f0: can't prepare media
其他尝试情况
- 用
videotestsrc替代intersink/intersrc方案时,推流和拉流功能正常。 - 尝试过
shmsink/src、手动设置caps的appsrc/sink等跨管道结构,拉流时两端都会冻结,最终超时返回503。其中appsrc方案中,由于客户端连接时才创建管道实例,无法在prepare前设置caps并推送缓冲区,因此改用intersink/src。
请教问题
- 如何以最小开销在管道间传递数据?
- 如何正确配置拉流端以转发传入的RTP数据包?(
rtppassthroughpay看起来可行,但仍需解决跨Media Factory的管道通信问题)
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

