(转)live555 RTSP Server RTP over TCP BUG
最近碰到一个非常棘手的问题,NVR通过ONVIF协议接入IPC进行录像,在录像时,会发现其中有个别IPC会出现录像断断续续的情况。这种情况很难复现,但是这种情况一旦出现,整个过程会一直持续很长时间,一般是直到重启RTSP Server。
通过苦逼型的大规模测试发现:
1、IPC与NVR之间是通过RTP over TCP的方式传输数据(这个测试结果很简单就可以知道);
2、开启1个客户端(通过RTP over TCP传输数据),打开rtsp流后,使用任务管理器强制结束。紧接着马上再开1个客户端,打开rtsp流,稍等一会儿(1分钟左右),后面开启的这个流居然自动断开了。这是一个必现的bug。(这里测试时,客户端可使用VLC,不过VLC默认情况下是使用RTP over UDP的方式传输数据。要使用 over TCP方式接收数据,需要通过以下设置: “工具”->“首选项”,打开首选项对话框后,“显示设置”处点击“全部”单选按钮,在左侧树形菜单依次展开:“输入/编解码器”->“去复用器”->“RTP/RTSP”,选中“使用RTP over RTSP(TCP)”);
通过调试发现:
1、RTSPServer::createNew()的参数里面有个reclamationTestSeconds参数,该参数默认值为65;
2、RTSPServer::createNewClientSession创建一个RTSPClientSession实例时,RTSPClientSession构造函数会调用noteLiveness,noteLiveness会设置一个延时任务,该任务的延时时间即为1中的reclamationTestSeconds(其值为秒,需要转换为微秒,回调为livenessTimeoutTask)。noteLiveness除了在构造的时候调用,在RTSP SERVER接收到一个RR数据包后,也会调用(RR其实也用作了一种心跳包了);
3、RTSPServer::incomingConnectionHandler()函数在异常结束上一个客户端后,再打开一个客户端打开rtsp流时,函数中accept返回的socket的值和上一个客户端的socket句柄值是相同的(概率在50%以上,如果这里返回的socket句柄不同,这个bug就不会复现了);
通过以上3条,如果你读过live555的代码,应该知道是怎么回事了。上面2中设置的延时任务的回调函数livenessTimeoutTask,只干了一件事件,就是delete掉RTSPServer::createNewClientSession创建的实例。查看RTSPClientSession的析构函数,发现其居然把RTPInterface::fTCPStreams链表中对应的节点给删掉了。而RTP和RTCP包是通过RTSPServer::sendPacket发送到各个客户端的,在发送的时候,就是直接对RTPInterface::fTCPStreams保存的地址(即socket句柄)进行发送。如果RTPInterface::fTCPStreams中的socket清除了,客户端自然不会再接收到数据,出现断线已经是必然了。至此,断线的原因终于明了:即异常结束掉一个客户端,在65秒内(默认值为65),再开启一个客户端打开流,第二次打开的这条流会在65秒内必然断开,如果客户端有断线自动重连的功能,那么,断断续续的情况就出现了。
通过测试还发现,通过RTP over UDP的方式接收数据时,异常结束客户端,RTSP Server居然会接收到一条TEARDOWN消息,而在TEARDOWN消息的处理过程中,会清理掉client session和RTSP链接,即使用RTP OVER UDP的方式传输数据时,异常结束客户端,并不会出现上述bug,这个让我困惑不少,如果哪位知道,请告诉我原因。
其实解决这个问题,只需要注释掉livenessTimeoutTask中的delete语句就行了,不过这不是最终解决方案,因为会造成内存泄漏,最好的方式是使用SESSION ID和目标地址进行关联,在调用StreamState::endPlaying删除目的地址时,如果SESSION ID不对应,不从链表中清除掉对应的节点就行了。
转自:http://m.blog.csdn.net/blog/zxwangyun/40541023
(转)live555 RTSP Server RTP over TCP BUG的更多相关文章
- 【视频开发】RTSP SERVER(基于live555)详细设计
/* *本文基于LIVE555的嵌入式的RTSP流媒体服务器一个设计文档,个中细节现剖于此,有需者可参考指正,同时也方便后期自己查阅.(本版本是基于2011年的live555) 作者:llf_17@q ...
- Live555研究之三 RTSP Server处理请求
RTSP Server会不断用select查询是否有socket连接,如果有则在(*handler->handlerProc)(handler->clientData, resultCon ...
- 一个RTSP/RTP over TCP 的丢包引起的问题
背景知识:可以查看https://www.cnblogs.com/lidabo/p/4483497.html RTSP/RTP over TCP TCP承载RTSP/RTP When you us ...
- RTSP - RTP over TCP
RTP over RTSP(TCP)(一) RTP over RTSP包混合发送的解决办法 RTSP - RTP over TCP To use TCP communication, ...
- 使用live555 在linux下搭建 rtsp server
系统环境 Debian 7 x64 / centos 7 x64 都可以 首先去下载源码 http://www.live555.com/liveMedia/public/live555-lates ...
- RTSP HTTP RTP RTCP
RTSP简介 RTSP(Real Time Streaming Protocol)是由Real Network和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议.RTSP对流 ...
- Managed Media Aggregation using Rtsp and Rtp
his article was written almost 2 years ago, it's content may not reflect the latest state of the cod ...
- live555 RTSP推送到Darwin出现404错误的解决
我们将Darwin部署到公网,接收live555 RTSP/RTP推送的时候,经常会出现在SETUP步骤Darwin返回404错误,经过查找原因,主要是Darwin对live555推送的sdp信息中的 ...
- 让EasyDarwin只支持RTP over TCP传输
我们经常需要EasyDarwin服务器支持公网流媒体传输,但很多时候,播放器默认都是通过RTP over UDP的形式在RTSP SETUP中请求,往往都以在内网接收不到UDP数据失败结束,那么我们如 ...
随机推荐
- [iOS]终极横竖屏切换解决方案
[iOS]终极横竖屏切换解决方案 大家的项目都是只支持竖屏的吧?大多数朋友(这其中当然也包括博主),都没有做过横屏开发,这次项目刚好有这个需求,因此把横竖屏相关的心得写成一遍文章供诸位参考. 01.综 ...
- android工程导入没有错误,运行提示Unable to instantiate activity ComponentInfo
导入小米clientside_android_sdk的demo OAuth-OpenAuthDemo,点Java Build Path的Libraries内Add External JARs,将oau ...
- VMware vCenter 资源池
VMware vCenter 资源池 1.简介 资源池是灵活管理资源的逻辑抽象.资源池可以分组为层次结构,用于对可用的 CPU 和内存资源按层次结构进行分区. 每台独立主机和每个DRS 群集都具有一个 ...
- replace()的使用方法
replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串. 数字类型的必须转换成字符串才能使用replace,否则会报错
- nohup 后台启动程序,并输出到指定日志
1.启动程序并输入到指定日志 nohup python manage.py runserver 0.0.0.0:9090 > /data/zyj/xadstat/xadstat.log 2&am ...
- 【神经网络】神经网络结构在命名实体识别(NER)中的应用
命名实体识别(Named Entity Recognition,NER)就是从一段自然语言文本中找出相关实体,并标注出其位置以及类型,如下图.它是NLP领域中一些复杂任务(例如关系抽取,信息检索等)的 ...
- Ubuntu 14.04快速搭建SVN服务器及日常使用
1.介绍 Subversion是一个自由,开源的版本控制系统,这个版本库就像一个普通的文件服务器,不同的是,它可以记录每一次文件和目录的修改情况.这样就可以很方面恢复到以前的版本,并可以查看数据更改 ...
- firefox快捷键窗口和标签类
firefox快捷键窗口和标签类: 关闭标签: Ctrl+W 或 Ctrl+F4关闭窗口: Ctrl+Shift+W 或 Alt+F4向左移动标签: Ctrl+左方向键 或 Ctrl+上方向键向右移动 ...
- Eigen教程(10)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html 混淆 在Eigen中,当变量同时出现在左值和右值,赋值操作可能会带来混淆问题.这一篇 ...
- Thinkphp动态切换主题
'DEFAULT_THEME' => '2014', 'TMPL_DETECT_THEME' => true, // 自动侦测模板主题 'THEME_LIST' => '2012,2 ...