2023年11月27日发(作者:)
live555代码分析
Live555
Live555是⼀个跨平台的C++开源项⽬,为流媒体提供解决⽅案,实现了RTP/RTCP、RTSP、SIP等标准流媒体传输协议。
Live555实现了⾳视频数据的流化、接收和处理。⽀持包括MPEG、H.253+、DV、JPEG等视频编码格式、及多种⾳频编码。⽬
前,Live555已经被⽤于多款播放器的流媒体播放功能的实现,如VLC(VideoLan)、MPlayer。
该项⽬的源代码包括四个基本的库,各种测试代码以及LIVE555 Media Server。
四个基本的库分别是UsageEnvironment&TaskScheduler,groupsock,liveMedia,BasicUsageEnvironment。
1、Live555 Streaming Media整体框架
(1) UsageEnvironment模块是对系统环境的抽象,包括 UsageEnvironment和TaskScheduler,⽤于事件的调度。
<1> UsageEnvironment主要⽤于消息的输⼊输出和⽤户交互功能。
<2> TaskScheduler实现事件的、事件处理函数的注册等,它通过维护⼀个异步读取源实现对诸如通信消息到达等事件的处理,通过使
⽤DelayQueue实现对其他注册函数的延时调度。
程序设计者通过⾃定义该抽象了类UsageEnvironment和TaskScheduler类的⼦类,就可以在特定环境(如GUI环境)中运⾏,不需要进
⾏过多的修改。
(2) BasicUsageEnvironment模块是UsageEnvironment的⼀个控制台应⽤的实现。它针对控制台的输⼊输出和信号响应进⾏具体实
现,利⽤select 实现事件获取和处理。
(3) GroupSock模块,对⽹络接⼝进⾏封装、⽤于实现的发送和接收。GroupSock主要被设计⽤以⽀持,但它也完全⽀持通信。
(4) LiveMedia模块是Live555中最重要的模块。该模块声明了⼀个Medium,其他所有类都派⽣⾃该类。
<1> RTSPClient:该类实现RTSP请求的发送和响应的解析,同时根据解析的结果创建对应的RTP会话。
<2> MediaSession:⽤于表⽰⼀个RTP会话,⼀个MediaSession可能包含
(5) Media Server 是⼀个纯粹的RTSP 服务器。⽀持多种格式的媒体⽂件:
l TS 流⽂件,扩展名ts。
l PS 流⽂件,扩展名mpg。
l MPEG-4视频基本流⽂件,扩展名m4e。
l MP3⽂件,扩展名mp3。
l WAV ⽂件(PCM),扩展名wav。
l AMR ⾳频⽂件,扩展名.amr。
l AAC ⽂件,ADTS 格式,扩展名aac。
1.1 OpenRTSP客户端流程
Ø MediaSession *pMediaSession = MediaSession::createNew(env,sdpDescription);
Ø bool hasSubSession = pMediaSession->hasSubsession();
Ø MediaSubsessionIterator *iter = //⼦会话迭代器
newMediaSubsessionIterator(*pMediaSession);
Ø MediaSubsession *pSubsession = iter->next();
Ø pSubsession->initiate();
Ø unsigned short num = pSubsession->clientPortNum(); //本地rtp端⼝
Ø 本体rtcp端⼝:num + 1
Ø //发送setup命令
<2>运⾏,弹出的dos框⾥⾯有地址,如下图
<3>客户端,dos下进⼊到ffplay所在⽂件夹下,然后输⼊如下命令
rtsp://10.120.2.18/<媒体⽂件名>
2、 编译live555
2.1 ⽅法1
利⽤⽣成VS可⽤的makefile
1 修改win32config。打开livewin32config⽂件,修改如下
TOOLS32 = c:ProgramTOOLS32 = E:Program FilesMicrosoft
FilesDevStudioVcVisual Studio 10.0VC
LINK_OPTS_0
= $(linkdebug)LINK_OPTS_0 = $(linkdebug)
将TOOLS32修改为你的VS2010路径
编译器索要的LINK运⾏库不同,原本以为可以改为
,但没找着
2 新增Makefile设定。打开,修改如下
INCLUDES = -Iinclude -INCLUDES = -Iinclude -I../UsageEnvironment/include -
I../UsageEnvironment/includeDNO_STRSTREAM
3 建⽴makefile
⽅法:运⾏,⽣成VS能够编译的*.mak⽂件
nmake /B -
5 开始编译:(命令⾏下)执⾏
5 编译结果:
5-1 在对应的⽂件下,如下图
① ⽣成与cpp⽂件对应的obj⽂件(Object File中间代码⽂件,源⽂件complie⽣成,在linux下为o⽂件)
② ⽣成lib库: 、、、
说明:若要⽤VS2010对代码进⾏调试跟踪,那么编译时需要做相应修改,修改⽅法如下:
⽅法⼀:修改*.mak⽂件下的NODEBUG 。不带DEBUG,NODEBUG=1(默认);带DEBUG,DEBUG=1
⽅法⼆:在win32config加⼊⼀⾏ "NODEBUG=1" (不推荐)
2.2 ⽅法2(Win7+VS2010⽅式)
如果需要⾃⼰调试修改源码,采⽤编译器的⽅式会更好些,这种⽅式也更利于源码分析,步骤如下:
0 综述:分别为每个库单独编译⽣成lib
..groupsockinclude
..liveMediainclude
..UsageEnvironmentinclude
3 添加⽂件。
for(char const*ptr = inputLine; *ptr != ‘0’; ++ptr)
{
if( *ptr== ‘r’ || *ptr == ‘n’ )
{ ++ptr;}
while(*ptr== ‘r’ || *ptr == ‘n’ )
{
++ptr;
}
nextLine =ptr; //即是下⼀⾏的开始
if(nextLine[0]== ‘0’)
{
p = * (phone number)
c = IN IP4 0.0.0.0 //连接信息
b =* (表⽰宽度信息,值为0或者bandwidth information)
t = * (time the session is active,有效时间)
r = * (zero or more repeat times)
a = control:*
a = range:clock= 20150120T180515Z – 20150405T151210Z
m = video 0 RTP/AVP 95 //视频
i = video media
a = rtpmap: 95 H264/90000
a = fmtp:95 profile-level-id = 4D0014; packetization-mode = 0
void* afterGettingClientData,
onCloseFunc* onCloseFunc,
void* onCloseClientData);
private:
Groupsock* fGS;
}
Boolean H254VideoRTPSource::processSpecialHeader(BufferedPacket*packet, unsigned& resultSpecialHeaderSize)
{
unsigned char* headerStart =packet->data;
unsigned frameSize, //数据帧的实际⼤⼩
unsigned numTruncatedBytes,
struct timeval presentationTime,
unsigned durationInMicroseseconds
);
Ø fSource是MediaSink 中的类型为FramedSource*的类成员。
3.3 数据流
数据经过多个Source到Sink。
Source1 -> Source2(a filter) -> … -> Sourcen(a filter) -> sink
从其他Source接收数据的Source也叫Filter。
5.1 rtsp client
5.1.1创建任务调度类TaskScheduler的对象
TaskScheduler* scheduler = BasicTaskScheduler::CreateNew();
ClassBasicTaskScheduler : public BasicTaskScheduler0
{
//创建对象,不能在外⾯通过构造函数创建对象
5.1.3创建RtspClient类
class RTSPClient : public Medium
{
public:
static RTSPClient* createNew( UsageEnvironment& env,
char const* rtspUrl,
struct timeval tv_timeToDelay;
tv__sec= 秒;
tv__usec = 毫秒;
int selectResult = select(fMaxNumSocket,&readSet, &writeSet, &exceptionSet, & tv_timeToDelay);
selectResult = 0; 表⽰超时
selectResult < 0; 表⽰错误
MediaSubsessionIterator it = newMediaSubsessionIterator(mediaSession);
创建MediaSubsession
MediaSubsession* pMediaSubsession = it->next();
pMediaSubsession->initiate();
}
class DummySink : public MediaSink
{
private:
RTPSource* fRtpSource;
FramedSource* fReadSouce; //帧数据源,RTP拆包后的H254帧数据
历史录像回放:absStartTime 按照格式yyyyMMddTHHmmss填写值
实时预览:absStartTime值为NULL
5.1.8发送Teardown命令关闭视频
Ø MediaSubsessionIterator *it;
delete it;


发布评论