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不对应,不从链表中清除掉对应的节点就行了。

时间: 2024-10-10 10:11:20

live555 RTSP Server RTP over TCP BUG的相关文章

(转)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 - RTP over TCP

Normally, RTSP provide streaming over UDP. By nature, UDP is a better choice as it provides robust streaming capability for media. However, it is unlikely to use UDP for streaming over the Internet. 通常来说,RTSP提供UDP方式发送RTP流.当然,发送流媒体时,UDP往往是更好的选择.但是,在互联

RTSP - RTP over TCP

Normally, RTSP provide streaming over UDP. By nature, UDP is a better choice as it provides robust streaming capability for media. However, it is unlikely to use UDP for streaming over the Internet. 通常来说,RTSP提供UDP方式发送RTP流.当然,发送流媒体时,UDP往往是更好的选择.但是,在互联

Streaming Video with RTSP and RTP

The Code In this lab you will implement a streaming video server and client that communicate using the Real-Time Streaming Protocol (RTSP) and send data using the Real-time Transfer Protocol (RTP). Your task is to implement the RTSP protocol in the c

RTSP server 在mips 上莫名其妙退出(PC上则无此问题)

http://blog.csdn.net/lubing20044793/article/details/38523701 早在这篇blog曾经写过,在虚拟机下调试sn9c291时,USB 传输数据出了问题.当时想兴许是virtualbox在usb 上对usb 2.0的支持尚未成熟导致的 所以当时也没管了,就继续在rt5350上调试sn9c291.(以为最新版本的virtualbox可以解决usb 2.0的问题,于是安装最新版本的virtualbox  4.3.16导致 虚拟机启动不了,退回4.3

mysqld启动“ Can't start server: Bind on TCP/IP port: Address already in use

[[email protected] ~]# vi /var/log/mysqld.log 进入log日志发现报以下的错误: 170901  4:56:54  InnoDB: Initializing buffer pool, size = 8.0M170901  4:56:54  InnoDB: Completed initialization of buffer pool170901  4:56:55  InnoDB: Started; log sequence number 0 44233

(转)live555 rtsp 客户端(openRTSP)使用注意事项

1:  编译 (1):  ./genMakefiles           linux (2):  make 2: 服务器环境 服务器端是一个支持RTSP server的H.264的摄像头; 3: 运行 openRTSP ./openRTSP  -d  20   -f  20  -w 640  -h  480   -b  400000  "rtsp://192.168.2.239/id=0" 或 ./openRTSP    -f  20  -w 640  -h  480   -b  4

修改mysql端口后重启mysql报错:Can't start server: Bind on TCP/IP port. Got error...n denied

1:错误信息:如下 [[email protected] ~]# systemctl status mariadb ● mariadb.service - MariaDB 10.2.30 database server Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/mariadb.service.d └─

live555 client 接收rtp数据

2014-03-08  22:05:58   描述live555 client即openRTSP的流程,简单点说,playCommon.cpp,流为h264和g726.在实际项目中已成功应用. 以下为我所见所得,有错误之处请指正,谢谢! 1.live555的三种任务 socket handler,event handler,delay task. 这三种任务的特点是,前两个加入执行队列后会一直存在,而delay task在执行完一次后会立即弃掉. 1 2 3 4 5 6 7 8 9 10 11