vlc客户端rtsp播放live555的.264文件
服务端只调用GenericMediaServer::ClientConnection类构造函数一次,在RTSPServer的基类GenericMediaServer的构造函数中,调用了turnOnBackgroundReadHandling并将其静态函数incomingConnectionHandler关联到fServerSocket。这样当有VLC客户端通过rtsp播放的时候,由于BasicTaskScheduler0::doEventLoop循环调用BasicTaskScheduler::SingleStep函数,执行刚刚关联的静态函数并继而调用同名函数进而调用GenericMediaServer::incomingConnectionHandlerOnSocket函数,在该函数中会调用createNewClientConnection函数。由于createNewClientConnection函数是GenericMediaServer类的虚函数,所以最终调用RTSPServerSupportingHTTPStreaming::createNewClientConnection函数创建RTSPServerSupportingHTTPStreaming::RTSPClientConnectionSupportingHTTPStreaming类对象,这个类继承自RTSPServer::RTSPClientConnection,而这个类又继承自GenericMediaServer::ClientConnection类。所以执行该构造函数一次。
当用vlc来请求一个Live555的264文件时,如果能正常播放则流程如下。其中在Live555服务端共调用RTSPServer::RTSPClientSession类构造函数一次,是在RTSPServer::RTSPClientConnection::handleRequestBytes函数中处理客户端发来的"Setup"消息的过程中,然后调用RTSPServer::RTSPClientSession::handleCmd_SETUP函数。在响应"Setup"消息过程中创建RTSPServer::RTSPClientSession对象,调用GenericMediaServer::createNewClientSessionWithId函数,在该 函数中首先生成一个随机值,然后以该随机值作为参数调用虚函数createNewClientSession,即执行RTSPServer::createNewClientSession来创建RTSPServer::RTSPClientSession对象。
其中在Live555服务端共调用ServerMediaSession类构造函数两次,第一次是在响应"Describe"消息的过程中,RTSPServer::RTSPClientConnection::handleCmd_DESCRIBE函数中首先调用GenericMediaServer::lookupServerMediaSession,该函数为虚函数所以会调用DynamicRTSPServer::lookupServerMediaSession函数,在该函数中首先用streamName作为参数调用基类的函数,如果没有找到就构造ServerMediaSession类对象并以streamName保存到基类的hash表fServerMediaSessions中,这样下次调用lookupServerMediaSession即可以查到。
在DynamicRTSPServer::lookupServerMediaSession函数中调用同文件中的静态函数createNewSMS,该函数调用ServerMediaSession类的构造函数,然后调用H264VideoFileServerMediaSubsession::createNew创建对象并作为参数调用ServerMediaSession::addSubsession函数。
这第二次调用ServerMediaSession类构造函数产生的对象在RTSPServer::RTSPClientSession::handleCmd_SETUP函数中赋值给RTSPServer::RTSPClientSession的基类GenericMediaServer::ClientSession中的成员ServerMediaSession* fOurServerMediaSession;而且注释为"We're accessing the "ServerMediaSession" for the first time."。然后根据ServerMediaSession对象包含的ServerMediaSubsession对象个数fSubsessionCounter来初始化RTSPServer::RTSPClientSession类的成员变量fStreamStates。这是一个指针对象,指向一个结构体数组,其中数组的每个元素代表一个子会话即ServerMediaSubsession对象。然后又会调用getStreamParameters,又因为该函数为虚函数,所以执行OnDemandServerMediaSubsession::getStreamParameters,该函数中首先创建继承自FramedSource类的H264VideoStreamFramer对象,然后又创建继承自RTPSink类的H264VideoRTPSink对象,然后以这两个对象创建StreamState对象来作为RTSPServer::RTSPClientSession类的成员fStreamStates所指的数组中子session的关联的void* streamToken;。然后将目的地址保存在子session的成员变量中,即OnDemandServerMediaSubsession类中的保护成员HashTable* fDestinationsHashTable;中。
下图所示为一次正常的客户端申请播放264视频所交互的rtsp消息及部分类的继承关系: