live555多线程改造方案
博主已经使用live555近10年,用作客户端可以每个线程一路live555 rtsp client,但是用作服务端,一直是单个线程处理,并发能力受限。
今年笔者所在公司对并发量有要求,200路,不得不研究对其进行多线程改造。
经过1个月的开发调试,终于实现,现在把基本思路分享一下:
1. 不改动live555的处理框架和逻辑
2. 处理sdp的生成函数,把同步等待修改为定时器等待。(不修改会导致新的请求导致前一路视频可能卡顿)
3. 增加N个Rtp发送线程,处理rtcp和rtp的发送
4. 修改类MultiFramedRTPSink,增加rtp发送线程的派发处理:
MultiFrame[......]
Live555用作标准的RTP发送和接收库
live555很多人用来做rtsp server或者rtsp client,其实也可以单独用作通用的rtp库。笔者就是对其进行稍作封装,命名为CRtpRecevier和CRtpSender类。这样就可应付很多rtp处理。
封装后基本可以一劳永逸的移植到各个平台上使用。live555支持的payload type比较全面。各种流行的媒体rtp封装都支持,不需要自己进行分帧和特殊处理,省很多事情。
代码性能和延时都有保证。音视频可小于80毫秒。
1. 用作rtp接收,可以参考我以前的博文
发送的核心逻辑是构造媒体的sdp字符串,然后live555内部会分析这个文本创建不同的解析类实例
Live555通过[......]
Live555接收RTP的Jitter Buffer机制(Live555 Rtp Receive Jitter Buffer)
用了Live555 5年了,今天想找一下它接收RTP的防网络抖动的处理机制,看看其jitter buffer缓存时间到底是多长,追踪源码,如愿以偿。
ReorderingPacketBuffer类就是其对接收的RTP包根据seqno序号进行排队的缓存队列,live555的缺省队列缓存是100毫秒,注意代码注释default reordering threshold: 100 ms;
具体代码如下:
ReorderingPacketBuffer
::ReorderingPacketBuffer(BufferedPacketFactory* packetFactory)
: fThresholdTime(1[......]
本软件工作室承接Android下的音视频流媒体APP快速开发
提供基于Android下的音视频相关的播放,采集,流媒体,RTP相关APP开发。基于MediaCodec H264硬编硬解,AAC,G711,G726等音频编解码等,性能绝佳,延时小于0.5秒,辅以jni调用ffmpeg转码及live555提供流媒体推送或拉取,确保项目开发周期短。
项目金额15000 RMB起。具体金额具体商谈,联系方式请点链接
1. libRtspClient Demo下载测试:
RTSP/RTMP流媒体播放库,可支持边录制,边播放。采用多线程支持多任务拉流。底层采用live555和ffmepg最新版本,可轻易支持android等平台。
RTSP支持onvif的用户密码认证。[......]
本软件工作室承接基于Live555的二次开发软件项目
RTSP服务端:可提供TS流直播,点播, mp4格式扩展的直播和点播, 各种定制的音频和视频流组合流的流媒体服务。
RTSP客户端项目包括:录制RTSP流媒体,存储文件(格式为mp4或者ts).
不管服务端还是客户端,可提供双视频流或多视频流以及多音频流的流媒体扩展。
包括但不限于:H264 + h264 + aac 3个以上track的RTSP流, 或 H264 + mjepg + aac 等3个以上track的RTSP流, 或者H264 + h263 + aac包括3个以上track的RTSP流。
可灵活定制推送多track,多种编码格式混合的流, 以及录制多种编码格式混合的mp4或者ts格式文件[......]
Live555性能优化实践
网上很多文章提到了Live555的单线程任务调度模式,在用作RTSP服务时,导致了在并发量较多或者磁盘性能不佳时会导致性能较差,并发数受限。笔者通过在做基于海思3531编码器和解码器的过程当中(提供基于2路H264+1路AAC的TS流编码(输入为RTSP TS流)和RTSP流媒体解码播放),有以下2点收获,特分享给有需要的同仁。
优化1:同步读取数据源修改为异步读取数据源, FramedSource的子类的doGetNextFrame函数中不要阻塞等待数据源, 在无数据时可以重新增加一个定时器任务,延时再读取数据。在无数据时增加一个等待任务:
{
if(无数据可读){//延时3000微妙(3毫秒)再次读取数据
envir().taskScheduler().scheduleDelayedTask(3000, (TaskFunc*)DelayReadFrame, this);
return;
}
.....省略其他正常逻辑
}
static void MyFramedSource::DelayReadFrame(FramedSource *sourc)
{
source->doGetNextFrame();
}
优化2:[......]
深刻理解Live555源码,掌握这把RTSP,RTP的瑞士军刀
我无意评价Live555的源码是否优雅易懂,但对于我这种C++设计模式应用不熟的IT老兵,还是很难直接通过阅读源码深刻清晰,一目了然的理解其中的调用逻辑。Live555中关于RTSP的Session,SubSession的概念,以及FramedSource和Sink的抽象都很不错的。但对于其任务单步调用机制,以及如何读取一帧数据及时发出一帧数据的全部逻辑, 真不容易得到清晰的处理逻辑。实践出真知,笔者本文就介绍一种通过运行时堆栈信息迅速理解关键代码和关键逻辑的方法。
先来观察本文尾部的GDB打印的堆栈信息,是笔者在实际开发中在Live555中扩展了mp4文件格式的支持,凡是ffmpeg_server目录下的的都[......]
Live555通过SDP文本信息实现对RTP的接收
笔者最近因为工做中需要用到此功能,特把实现方法分享给有兴趣的网友。
我的方法来自Live555官方论坛最权威的方案,如下:
[Live-devel] Once again, SDP support for Live555 & interaction with FFMpeg
1.First, create a “MediaSession” object, by calling
“MediaSession::createNew()”, with the SDP description (string) as
parameter.
2.Then, go through each of this obj[......]
Live555用做RTSPClient时,利用RTP时间戳进行音视频同步的解决方案(必须有RTCP支持才可行)
先看来自Live555官网的2个常见问题:
问题1:Why do most RTP sessions use separate streams for audio and video? How can a receiving client synchronize these streams?
回答:Sending audio and video in separate RTP streams provides a great deal of flexibility. For example, this makes it possible for a player to receive only the audio[......]
Live555 + Darwin Streaming Server(DSS)视频直播方案
function writeSpace( num){ var i;
for(i = 0; i < num; ++i)
{ document.write(' ' ); }
}
该方案的实现原理是,通过Live555的DarwinInjector Class,把本地采集的音频和视频流,注入到DSS服务器。客户端就可以直接访问DSS服务器(不是Live555所在的采集端)来访问实时流媒体数据。
这种方案的优点:
》保证了单台DSS服务器并发量可以上几百。
》DSS服务可以像承载点播一样,实现直播。
》支持多路直播,就跟增加一个点播文件一样简单。
缺点:
》延时一般需要5秒左右
》直播集群支持节点受限,一台PC运行Live555采集端可同时注入的DSS服务器数量不超过5台
首先需要修改DSS服务端配置:
这里需要设置一下/usr/local/movies/目录的QTSS访问权限,允许写入:
修改DSS配置,增加文件:vi /usr/local/movies/qtaccess,增加以下几行
require any-user
require any-user
基本原理图如下:
writeSpace(38); /—-【客户端 1 RTSP Client(例如VLC)】
【采集客户端调用Live555 DarwinInjector】 —-> 【DSS 服务器 192.168.1.22】《—–【客户端 2 RTSP Client(例如VLC)】
writeSpace(38); \—-【客户端 N RTSP Client(例如VLC)】
方案的实现流程,用伪代码来说明:
0. 调用live555中已有的类创建Darwin i[......]