首先,看看这个程序的说明:
// A test program that demonstrates how to stream - via unicast RTP
// - various kinds of file on demand, using a built-in RTSP server.
就是说这个程序演示了如何利用RTSPServer这个类来对媒体文件进行单播,OnDemand的意思是收到RTSP客户端请求时才进行流化和单播。
下面,首先看main函数,很简单,主要包含以下几个步骤:
// Begin by setting up our usage environmen
// 创建工具类
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
env = BasicUsageEnvironment::createNew(*scheduler);
// Create the RTSP server:
// 创建RTSPServer,指定端口为8554
RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB);
if (rtspServer == NULL) {
*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
exit(1);
}
char const* descriptionString
= "Session streamed by \"testOnDemandRTSPServer\"";
// Set up each of the possible streams that can be served by the
// RTSP server. Each such stream is implemented using a
// "ServerMediaSession" object, plus one or more
// "ServerMediaSubsession" objects for each audio/video substream.
/* 为每一种媒体文件创建会话,简单理解就是:一个ServerMediaSession对象对应一个媒体文件,一个媒体文件中可能同时包含音频和视频,对于每个视频或者音频,对应一个ServerMediaSubsession对象,
一个ServerMediaSession中可以包含多个ServerMediaSubsession对象 */
// 这里我们只看H.264文件
// A H.264 video elementary stream:
{
char const* streamName = "h264ESVideoTest"; //标识请求播放该媒体文件时使用的名称
char const* inputFileName = "test.264"; //默认媒体文件名为test.264
ServerMediaSession* sms = ServerMediaSession::createNew(*env, streamName, streamName,descriptionString); //为该媒体文件创建一个ServerMediaSession
/* .264文件只包含视频,创建一个ServerMediaSubsession对象并添加到ServerMediaSession
H264VideoFileServerMediaSubsession是ServerMediaSubsession的子类,针对不同格式有不同的实现类 */
sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(*env, inputFileName, reuseFirstSource));
rtspServer->addServerMediaSession(sms); //将刚才创建的ServerMediaSession添加到RTSPServer中
announceStream(rtspServer, sms, streamName, inputFileName); //打印出播放该媒体文件的rtsp地址
}
// 程序从下面开始进入一个主循环,后面的return 0不会被执行。
env->taskScheduler().doEventLoop(); // does not return
return 0; // only to prevent compiler warning
Live555是单线程的,基于事件驱动模式,程序从doEventLoop函数出进入无限循环,在这个循环中不断地查看事件队列是否有事件需要去处理,有就去处理,没有则休眠一小会儿,看下doEventLoop函数,该函数在live/BasicUsageEnvironment/BasicTaskScheduler0.cpp文件中定义。
void BasicTaskScheduler0::doEventLoop(char* watchVariable) {
// Repeatedly loop, handling readble sockets and timed events:
while (1) {
if (watchVariable != NULL && *watchVariable != 0) break;
SingleStep();
//SingleStep函数中,对可读数据的socket进行读数据,对事件队列中的事件调用对应的处理函数处理
}
}
主循环部分的代码比较简单,那我们就需要仔细看看创建RTSPServer,创建ServerMediaSession以及ServerMediaSubsession这部分的代码,看这