问题描述
在3年前我当时基于EasyDarwin为用户开发了一款RTSP拉模式转发的程序,也发布了一篇博客《用Darwin开发RTSP级联服务器(拉模式转发)》,当时考虑的很简单,只要将RTSP源的sdp和RTP流拉取过来,不做任何变动立即转发即可实现拉模式转发了,而且CPU占用也会非常低,基本上就是跑一个数传,其效果也正如预期的那样,一个EasyDarwin拉模式转发的服务器,可以带动很多个IPC的流分发,再次以RTSP+RTP协议的形式分发出去;
但是,近期有我们的一位EasyDarwin的用户反馈道:转发大部分的IPC都是没有问题的,但是转发海康的某几款设备的时候,总是会出现花屏,而且是必现的!?!
问题排查
再次重新操刀负责此事,我决定拆分拉模式转发的流程,做排除法进行分析:
- 第一步是IPC到EasyDarwin的数据是否完整;
- 第二步是EasyDarwin的RTSPClient的数据是否完整;
- 第三步是RTSPClient是否将有效的数据丢掉了;
我们先从第三部分开始,直接通过EasyRTSPClient从EasyDarwin获取转发的RTSP流,存储到文件,其试用方法可以参考博客《[工具]利用EasyRTSPClient工具检查摄像机RTSP流不能播放原因以及排查音视频数据无法播放问题》,我发现存储下来的H.264文件确实就是花屏的;
我们再从第一部分开始排查,我们选择从服务器端打印RTP序列号的方式来进行的,因为比较简单,当发现上一个RTP Number跟下一个RTP Number不连续的时候,我们就打印日志,结果发现,始终都很连续,非常稳定!排除此部分的问题!
再排查第二个部分就是EasyDarwin到RTSPClient的RTP流是否完整了,这一部分我们采用了wireshark抓包的方式,查看RTP Sequence是否是连续的,结果发现也是RTP非常连续的,没有遗漏,也就是说,数据也确实都完整地转发到了客户端!排除此部分的问题!
那么问题就出在了RTSPClient阶段,是如何将收到的数据,却给丢掉了!
通过反复打印EasyRTSPClient中的日志,我们发现了一段代码如图:
海康的RTP流在RTP中设置的Padding为True,也就是尾部有附加数据,而我们转发的时候却只转发的RTP部分,附带的部分没有进行转发,结果就导致RTSPClient将这部分数据认为是不完整的数据,直接丢掉了,那么就导致了花屏的产生!
解决方案
我们在EasyDarwin中人为地将Padding字段设置为0就可以了,这样附加数据也不用转发了,只转发视频部分:
关于EasyRTSPClient
EasyRTSPClient是一套非常稳定、易用、支持重连的RTSPClient工具,SDK形式提供,接口调用非常简单,再也不用像调用live555那样处理整个RTSP OPTIONS/DESCRIBE/SETUP/PLAY的复杂流程,担心内存释放的问题了,全平台支持(包括Windows/Linux 32&64,ARM各平台,Android,iOS),支持RTP Over TCP/UDP,支持断线重连,连续维护与迭代超过5年,能够接入市面上99%以上的IPC,调用简单且成熟稳定!
获取更多信息
Copyright © EasyDarwin.org 2012-2017