mediaServer/live555MediaServer.cpp
==> main
1.RTSPServer::RTSPServer这个是live555MediaServer监听客户端连接的默认处理函数,监听端口为554(root权限执行)或8554
incomingConnectionHandlerRTSP
2.RTSPServer::setUpTunnelingOverHTTP通过http为rtsp做一个tunneling隧道,端口80或8000或8080,即RTSP-over-HTTP tunneling
incomingConnectionHandlerHTTP
3.
RTSPServer::RTSPClientSession::RTSPClientSession
incomingRequestHandler
上面的incomingConnectionHandlerRTSP和incomingConnectionHandlerHTTP最终都会调用
下面的incomingConnectionHandler统一处理函数
void RTSPServer::incomingConnectionHandler(int serverSocket) {
struct sockaddr_in clientAddr;
SOCKLEN_T clientAddrLen = sizeof clientAddr;
int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrLen); // 一个client尝试连接本server
if (clientSocket < 0) {
int err = envir().getErrno();
if (err != EWOULDBLOCK) {
envir().setResultErrMsg("accept() failed: ");
}
return;
}
makeSocketNonBlocking(clientSocket);
increaseSendBufferTo(envir(), clientSocket, 50*1024);
#ifdef DEBUG
envir() << "accept()ed connection from " << our_inet_ntoa(clientAddr.sin_addr) << '\n';
#endif
// Create a new object for this RTSP session.
// (Choose a random 32-bit integer for the session id
//(it will be encoded as a 8-digit hex number). We don't bother checking for
// a collision; the probability of two concurrent sessions getting the same session id is very low.)
unsigned sessionId = (unsigned)our_random();
(void)createNewClientSession(sessionId, clientSocket, clientAddr); // 将这个client添加到select中,随后与该client进行的一切数据交互
// 都将由incomingRequestHandler函数处理.
}
4. env->taskScheduler().doEventLoop(); 将使系统进入 select 或 poll ,等待554或8554或80或8000或8080端口上client客户端程序的连接.
它将调用 BasicTaskScheduler::SingleStep 完成 select 操作,即:
select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay);
5. RTSPServer::RTSPClientSession::incomingRequestHandler 这是连接到本 live555MediaServer 服务器的 client 随后数据处理函数
如下是 live555MediaServer 打开 client 希望打开的媒体文件
server 会打开该文件,同时根据文件后缀名,创建解析该类型文件的结构体,
然后边解析数据边回传给client,所以live555MediaServer只支持它自己支持的audio/video文件
RTSPServer::RTSPClientSession::handleCmd_DESCRIBE
==> fOurServer.lookupServerMediaSession(urlSuffix) // 这里的urlSuffix内容对应上面的"1.mp3"字符串
==> DynamicRTSPServer::lookupServerMediaSession
==> RTSPServer::lookupServerMediaSession(streamName)
==> sms = createNewSMS(envir(), streamName, fid); // Create a new "ServerMediaSession" object for streaming from the named file.
// 该函数为live555MediaServer所支持的所有audio/video文件格式,如果需要扩展,可以将其加入进来[luther.gliethttp]
// 至少没有看到对.mp4和.3gp的支持
static ServerMediaSession* createNewSMS(UsageEnvironment& env,
char const* fileName, FILE* /*fid*/) {
//处理.264 .265 .mp3 等音频视频文件
}
ServerMediaSession* DynamicRTSPServer::
lookupServerMediaSession(char const* streamName, Boolean isFirstLookupInSession){
//createNewSMS()
} //类 GenericMediaServer 也有 <span style="font-family: Arial, Helvetica, sans-serif;">lookupServerMediaSession 虚函数</span>
有一个继承关系,从子到父:
DynamicRTSPServer → RTSPServerSupportingHTTPStreaming → RTSPServer → GenericMediaServer → Medium
在类 RTSPServerSupportingHTTPStreaming 调用lookupServerMediaSession()
void RTSPServerSupportingHTTPStreaming::RTSPClientConnectionSupportingHTTPStreaming
::handleHTTPCmd_StreamingGET(char const* urlSuffix, char const* /*fullRequestStr*/) {
//ServerMediaSession* session = fOurServer.lookupServerMediaSession(streamName);
}
fOurServer 是 GenericMediaServer.hh中类GenericMediaServer的一个public成员 类ClientConnection 中的 protected 成员 GenericMediaServer& fOurServer;