您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > live555源代码简介
live555源代码简介liveMedia项目的源代码包括四个基本的库,各种测试代码以及LIVE555MediaServer。四个基本的库分别是UsageEnvironment&TaskScheduler,groupsock,liveMedia,BasicUsageEnvironment。UsageEnvironment和TaskScheduler类用于事件的调度,实现异步读取事件的句柄的设置以及错误信息的输出。另外,还有一个HashTable类定义了一个通用的hash表,其它代码要用到这个表。这些都是抽象类,在应用程序中基于这些类实现自己的子类。groupsock类是对网络接口的封装,用于收发数据包。正如名字本身,Groupsock主要是面向多播数据的收发的,它也同时支持单播数据的收发。Groupsock定义了两个构造函数Groupsock(UsageEnvironment&env,structin_addrconst&groupAddr,Portport,u_int8_tttl);Groupsock(UsageEnvironment&env,structin_addrconst&groupAddr,structin_addrconst&sourceFilterAddr,Portport);前者是用于SIM(source-independentmulticast)组,后者用于SSM(source-specificmulticast)组。groupsock库中的Helper例程提供了读写socket等函数,并且屏蔽了不同的操作系统之间的区别,这是在GroupsockHelper.cpp文件中实现的。liveMedia库中有一系列类,基类是Medium,这些类针对不同的流媒体类型和编码。各种测试代码在testProgram目录下,比如openRTSP等,这些代码有助于理解liveMedia的应用。MediaServer是一个纯粹的RTSP服务器。支持多种格式的媒体文件:*TS流文件,扩展名ts。*PS流文件,扩展名mpg。*MPEG-4视频基本流文件,扩展名m4e。*MP3文件,扩展名mp3。*WAV文件(PCM),扩展名wav。*AMR音频文件,扩展名.amr。*AAC文件,ADTS格式,扩展名aac。用live555开发应用程序基于liveMedia的程序,需要通过继承UsageEnvironment抽象类和TaskScheduler抽象类,定义相应的类来处理事件调度,数据读写以及错误处理。live项目的源代码里有这些类的一个实现,这就是“BasicUsageEnvironment”库。BasicUsageEnvironment主要是针对简单的控制台应用程序,利用select实现事件获取和处理。这个库利用Unix或者Windows的控制台作为输入输出,处于应用程序原形或者调试的目的,可以用这个库用户可以开发传统的运行与控制台的应用。通过使用自定义的“UsageEnvironment”和“TaskScheduler”抽象类的子类,这些应用程序就可以在特定的环境中运行,不需要做过多的修改。需要指出的是在图形环境(GUItoolkit)下,抽象类TaskScheduler的子类在实现doEventLoop()的时候应该与图形环境自己的事件处理框架集成。基本概念先来熟悉在liveMedia库中Source,Sink以及Filter等概念。Sink类及其子类就是消费数据的对象,比如把接收到的数据存储到文件,这个文件就是一个Sink。Source类及其子类就是生产数据的对象,比如通过RTP读取数据。数据流经过多个'source'和'sink's,下面是一个示例:source1-source2(afilter)-source3(afilter)-sink从其它Source接收数据的source也叫做filters。Module是一个sink或者一个filter。数据接收的终点是Sink类,MediaSink是所有Sink类的基类。MediaSink的定义如下:classMediaSink:publicMedium{public:staticBooleanlookupByName(UsageEnvironment&env,charconst*sinkName,MediaSink*&resultSink);typedefvoid(afterPlayingFunc)(void*clientData);BooleanstartPlaying(MediaSource&source,afterPlayingFunc*afterFunc,void*afterClientData);virtualvoidstopPlaying();//Testforspecifictypesofsink:virtualBooleanisRTPSink()const;FramedSource*source()const{returnfSource;}protected:MediaSink(UsageEnvironment&env);//abstractbaseclassvirtual~MediaSink();virtualBooleansourceIsCompatibleWithUs(MediaSource&source);//calledbystartPlaying()virtualBooleancontinuePlaying()=0;//calledbystartPlaying()staticvoidonSourceClosure(void*clientData);//shouldbecalled(onourselves)bycontinuePlaying()whenit//discoversthatthesourcewe'replayingfromhasclosed.FramedSource*fSource;private://redefinedvirtualfunctions:virtualBooleanisSink()const;private://Thefollowingfieldsareusedwhenwe'rebeingplayed:afterPlayingFunc*fAfterFunc;void*fAfterClientData;};Sink类实现对数据的处理是通过实现纯虚函数continuePlaying(),通常情况下continuePlaying调用fSource-getNextFrame来为Source设置数据缓冲区,处理数据的回调函数等,fSource是MediaSink的类型为FramedSource*的类成员;基于liveMedia的应用程序的控制流程如下:应用程序是事件驱动的,使用如下方式的循环while(1){查找需要完成的任务(通过查找delayqueue和networkreadhandlers列表);完成此任务;}在进入这个循环之前,对于每个sink,应用程序通常调用下面的方法来启动需要做的生成任务:someSinkObject-startPlaying();数据链条流经过多个'source'和'sink's'source1'-'source2'(afilter)-'source3'(afilter)-'sink'(从其它Source接收数据的source也叫做filters)任何时候,一个Module(a'sink'oroneoftheintermediatefilter'source's)需要获取数据都通过调用刚好在它之前的那个Module的FramedSource::getNextFrame()方法。这是通过纯虚函数FramedSource::doGetNextFrame()实现的,每一个Sourcemodule都有相应的实现。Each'source'module'simplementationofdoGetNextFrame()worksbyarrangingforan'aftergetting'functiontobecalled(fromaneventhandler)whennewdatabecomesavailableforthecaller.(不好翻译)注意:任何应用程序都要处理从'sources'到'sinks'的数据流,但是并非每个这样的数据流都与从网络接口收发数据相对应。比如,一个服务器应用程序发送RTP数据包的时候用到一个或多个RTPSinkmodules。这些RTPSinkmodules以别的方式接收数据,通常是文件*Sourcemodules(e.g.,toreaddatafromafile),and,asasideeffect,transmitRTPpackets.一个简单的RTSP客户端程序在另一个文章里,给出了这个简单的客户端的程序的代码,可以通过修改Makefile来裁剪liveMedia,使得这个客户端最小化。此客户端已经正常运行。首先是OPTION然后是DESCRIBE建立MediaSession,调用的函数是MediaSession::createNew,在文件liveMedia/MediaSession.cpp中实现。为这个MediaSession建立RTPSource,这是通过调用MediaSubsession::initiate来实现的的,这个方法在liveMedia/MediaSession.cpp中实现。再然后是SETUP最后是PLAYrtp数据的句柄:MultiFramedRTPSource::networkReadHandler在liveMedia/MultiFramedRTPSource.cpp中rtcp数据处理的句柄:RTCPInstance::incomingReportHandler在liveMedia/RTCP.cpp中rtp数据处理的句柄的设置:MultiFramedRTPSource:doGetNextFrame在liveMedia/MultiFramedRTPSource.cpp中,被FileSink::continuePlaying调用在FileSink.cpp中.rtcp数据处理的句柄设置fRTCPInstance=RTCPInstance::createNew在/liveMedia/MediaSession.cpp中调用,createNew调用了构造函数RTCPInstance::RTCPInstance,这个构造函数有如下调用TaskScheduler::BackgroundHandlerProc*handler=(TaskScheduler::BackgroundHandlerProc*)&incomingReportHandler;*********************************************************************************************************************通过分析live库提供的例子程序OpenRTSP,可以清晰地了解客户端接收来自网络上媒体数据的过程。注意,RTP协议和RTCP协议接收的数据分别是视音频数据和发送/接收状况的相关信息,其中,RTP协议只负责接收数据,而RTCP协议除了接收服务器的消息之外,还要向服务器反馈。openRTSP.cppmain函数流程main(intargc,char*argv[]){1.创建BasicTaskScheduler对象2.创建BisicUsageEnvironment对象3.分析argv参数,(最简单的用法是:openRTSPrtsp://172.16.24.240/mpeg4video.mp4)以便在下面设置一些相关参数4.创建RTSPClient对象5.由RTSPClient对象向服务器发送OPTION消息并接受回应6.产生SDPDescription字符串(由R
本文标题:live555源代码简介
链接地址:https://www.777doc.com/doc-2885104 .html