char const* streamName = "h264ESVideoTest"; char const* inputFileName = "test.264"; ServerMediaSession* sms = ServerMediaSession::createNew(*env, streamName, streamName, descriptionString); sms->addSubsession(H264VideoFileServerMediaSubsession ::createNew(*env, inputFileName, reuseFirstSource)); rtspServer->addServerMediaSession(sms); announceStream(rtspServer, sms, streamName, inputFileName);
注意箭头所示。
class ServerMediaSession: public Medium { //精简版 public: char* generateSDPDescription(); // based on the entire session // Note: The caller is responsible for freeing the returned string Boolean addSubsession(ServerMediaSubsession* subsession); unsigned numSubsessions() const { return fSubsessionCounter; } void deleteAllSubsessions(); // Removes and deletes all subsessions added by "addSubsession()", returning us to an 'empty' state // Note: If you have already added this "ServerMediaSession" to a "RTSPServer" then, before calling this function, // you must first close any client connections that use it, // by calling "RTSPServer::closeAllClientSessionsForServerMediaSession()". private: // Linkage fields: friend class ServerMediaSubsessionIterator; ServerMediaSubsession* fSubsessionsHead; ServerMediaSubsession* fSubsessionsTail; unsigned fSubsessionCounter; char* fStreamName; char* fInfoSDPString; char* fDescriptionSDPString; char* fMiscSDPLines; struct timeval fCreationTime; unsigned fReferenceCount; Boolean fDeleteWhenUnreferenced; };即可明白其主要维护的是一个流的描述信息, 及管理多个ServerMediaSubsession.
对于文件存储来说, 其对应于该文件信息, 而ServerMediaSubsession则对应于该媒体文件的多个track, 且由ServerMediaSession管理.
代码中另一个看上去与Session有关的类RTSPClientSession则是与每个客户的rtsp连接相关联的。
先休息,后面继续针对OnDemandServerMediaSubsession等展开讨论下sdp的生成等细节