官方文档:http://www.live555.com/liveMedia/doxygen/html/annotated.html
详细介绍了live555中的每一个数据结构,以及他们之间的相关关系。
这个类主要用于消息的输入输出,例如输出错误/警告信息, 这个类也是比较重要的基础类,代表了整个系统的运行环境,所有的类中基本上都包含了这个类,用于输入输出错误信息,或者添加计划任务等。
下图是UsageEnvironment 类的继承图(来自 http://www.live555.com/liveMedia/doxygen/html/classUsageEnvironment.html):
这个类的主要工作便是用于监听端口、异步读取事件、调度任务、执行任务。上面的类UsageEnvironment是全局唯一的,TaskScheduler会将自己添加进去。因此其它类都可以通过UsageEnvironment来添加计划任务,如下:
envir().taskScheduler().setBackgroundHandling(fOurSocket, SOCKET_READABLE|SOCKET_EXCEPTION, incomingRequestHandler, this);
TaskScheduler在全局中只有一个,因此可以得知live555是单线程的。
下图是TaskScheduler的继承图(来自http://www.live555.com/liveMedia/doxygen/html/classTaskScheduler.html):
这个类关注不太多,只知道定义了一个通用的hash表,其它的代码要用到这个类。
摘抄自网上的一段话:
在LIVE555中,有很多地方需要用到该哈希表类,如媒体文件名与MediaSession的映射,SessionID与ClientSession的映射,UserName和Password的映射等
根据2.1 我们可以看到BasicUsageEnvironment是UsageEnvironment的子类,主要是对UsageEnvironment中类的实现。
这个类比较重要,有一系列的子类用于不同类型的流媒体和编码,也包含了RTSP相关的类。
下图是Medium的继承图(来自http://www.live555.com/liveMedia/doxygen/html/classMedium.html ):
继承自父类Socket,封装了对Socket的操作。用于收发数据,同时也支持多播或者一对多单播。只支持UDP,不支持TCP.。
对各种socket操作的封装,用于收发数据。主要面向组播,但也可以进行单播的收发数据,仅支持UDP,不支持TCP
下图是GroupSocket的继承图(来自http://www.live555.com/liveMedia/doxygen/html/classGroupsock.html):
MediaSource是所有Source的基类,继承自Medium。
下图是MediaSource的继承图(来自http://www.live555.com/liveMedia/doxygen/html/classMediaSource.html):
从上图可以看到,FramedSource继承自MediaSource,下面着重讲解一下FramedSource。
在这个类中,首先需要关注两个函数:getNextFrame , doGetNextFrame
getNextFrame函数如下:
void FramedSource::getNextFrame(unsigned char* to, unsigned maxSize,
afterGettingFunc* afterGettingFunc,
void* afterGettingClientData,
onCloseFunc* onCloseFunc,
void* onCloseClientData) {
// Make sure we're not already being read:
if (fIsCurrentlyAwaitingData) {
envir() << "FramedSource[" << this << "]::getNextFrame(): attempting to read more than once at the same time!\n";
envir().internalError();
}
fTo = to;
fMaxSize = maxSize;
fNumTruncatedBytes = 0; // by default; could be changed by doGetNextFrame()
fDurationInMicroseconds = 0; // by default; could be changed by doGetNextFrame()
fAfterGettingFunc = afterGettingFunc;
fAfterGettingClientData = afterGettingClientData;
fOnCloseFunc = onCloseFunc;
fOnCloseClientData = onCloseClientData;
fIsCurrentlyAwaitingData = True;
doGetNextFrame();
}
前面一大部分就是同步一些参数和设置回调函数,然后接着调用doGetNextFrame函数。
doGetNextFrame在这个类中是一个虚函数,留给子类实现。
参考例程testOnDemandRTSPServer中关于H264的RTSP部分,H264VideoFileServerMediaSubsession.cpp中,在createNewStreamSource函数中创建了Source, 如下:
ByteStreamFileSource* fileSource = ByteStreamFileSource::createNew(envir(), fFileName);
ByteStreamFileSource继承自FramedFileSource, FramedFileSource继承自FramedSource。 因此当FramedSource调用doGetNextFrame函数时候,会调用子类ByteStreamFileSource中的doGetNextFrame,其实现如下:
void ByteStreamFileSource::doGetNextFrame() {
if (feof(fFid) || ferror(fFid) || (fLimitNumBytesToStream && fNumBytesToStream == 0)) {
handleClosure();
return;
}
#ifdef READ_FROM_FILES_SYNCHRONOUSLY
doReadFromFile();
#else
if (!fHaveStartedReading) {
// Await readable data from the file:
envir().taskScheduler().turnOnBackgroundReadHandling(fileno(fFid),
(TaskScheduler::BackgroundHandlerProc*)&fileReadableHandler, this);
fHaveStartedReading = True;
}
#endif
}
可以看到,doGetNextFrame函数中,会调用其它函数从文件中读取文件发给Sink。因此,当我们想要实现直播流的时候,需要重写doGetNextFrame函数。
MediaSink是所有Sink的基类,继承自Medium。
下图是MediaSink的继承图(来自http://www.live555.com/liveMedia/doxygen/html/classMediaSink.html):
这个类的主要工作是用于将传输过来的流进行保存,这里不再讲解。
这个类主要用来向FramedSource请求媒体帧,然后FramedSource将取到的媒体帧回调给RTPSink,然后RTPSink将数据处理发给客户端或者保存到本地文件。因此在这类类里面有一些流操作的函数,如:startPlaying,stopPlaying,continuePlaying等等(有些已经在其父类中实现)。
下图是RTPSink的继承图(来自http://www.live555.com/liveMedia/doxygen/html/classRTPSink.html):
这个类主要用于和RTSP Client端进行交互。
下图是RTSPServer的继承图(来自http://www.live555.com/liveMedia/doxygen/html/classRTSPServer.html):
该类用于表示一个流媒体会话,连接了RTSPServer和下层流媒体的传输逻辑。
下图是ServerMediaSession的继承图(来自http://www.live555.com/liveMedia/doxygen/html/classServerMediaSession.html
):
ServerMeidaSubsession代表了ServerMeidaSession中的一个视频流或者音频流。因此一个ServerMeidaSession可以有多个ServerMeidaSubsession。
下图是ServerMeidaSubsession的继承图(来自http://www.live555.com/liveMedia/doxygen/html/classServerMediaSubsession.html):