锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / 流媒体开源技术 / live555的RTSP服务运行机制分析
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883

live555的RTSP服务运行机制分析

主要类关系如下
-------- DynamicRTSPServer----------------RTSPServerSupportingHTTPStreaming----------------RTSPServer提供虚函数接口--------------------------------------Medium  
--------   RTSPServer主要功能总结

  1. --------主要定义了一些错误处理函数接口(handleCmd_bad,handleCmd_notSupported)
  2. --------RTSPClientConnection类(handleCmd_OPTIONS,handleCmd_DESCRIBE)-----------------------------------------这些全是针对rtsp协议命令的处理
  3. --------RTSPClientSession类(handleCmd_SETUP,handleCmd_PLAY)
  4. --------RTSPClientConnection与RTSPClientSession分开定义,应该是这几个命令处理过程差别明显,下面详细介绍
  5. --------fAllowStreamingRTPOverTCP设置类rtp传输方式控制标志,通过以上说明大致了解了这个类的作用

testH264VideoStreamer.例子中创建了 RTSPServer* rtspServer,直接引用创建,说明其是全局变量,一个服务端对应一个
rtspServer->addServerMediaSession(sms);
play();开始播放
//void addServerMediaSession(ServerMediaSession* serverMediaSession) {--fServerMediaSessions是对应ServerMediaSession has表、全局只有一个,对应RTSPServer
//  fServerMediaSessions->Add(sessionName, (void*)serverMediaSession);                                                                                                                                                               这样我们了解到RTSPServer还提供了hash表等控制全局的数据结构
//}

RTSP 首先需建立 TCP 侦听 socket。可见于此函数:
[cpp]view plaincopyprint?
初始化流程大体如下
1、 RTSPServer::createNew(UsageEnvironment& env, Port ourPort,
 int ourSocket = setUpOurSocket(env, ourPort); //----根据port 建立 TCP socket,设置缓冲区
}

  1. RTSPServer::RTSPServer(UsageEnvironment& env,

{
env.taskScheduler().turnOnBackgroundReadHandling(fRTSPServerSocket,
(TaskScheduler::BackgroundHandlerProc*)&incomingConnectionHandlerRTSP, this);
}
void turnOnBackgroundReadHandling(int socketNum, BackgroundHandlerProc* handlerProc, void* clientData) {
setBackgroundHandling(socketNum, SOCKET_READABLE, handlerProc, clientData);-------------此函数是不是很熟悉!!!!,创立对应本地套接字处理函数incomingConnectionHandlerRTSP
}

  1. incomingConnectionHandlerRTSP

{---------
(void)createNewClientConnection(clientSocket, clientAddr);//Create a new object for handling this RTSP connection:可以理解为
}
RTSPServer::RTSPClientConnection::RTSPClientConnection(RTSPServer& ourServer, int clientSocket, struct sockaddr_in clientAddr)
{
envir().taskScheduler().setBackgroundHandling(fClientInputSocket, SOCKET_READABLE|SOCKET_EXCEPTION,----与上面类似,此处设置incomingRequestHandler,接下来如果有数据就调用handleRequestBytes              (TaskScheduler::BackgroundHandlerProc*)&incomingRequestHandler, this);
}

4、RTSPServer::RTSPClientConnection::handleRequestBytes(int newBytesRead) {---------------接下来正真处理客户端发来的数据,尼玛的这个路好漫长!!!!
{
parseRTSPRequestString(------)                                                   -------------------------------------------------------------------------解析rtsp的数据
handleCmd_DESCRIBE(------)                                                     -------------------------------------------------------------------------创立了ServerMediaSession,一

ServerMediaSession

ServerMediaSession------------------------------------------------------------------------------------------------Medium
class ServerMediaSession: public Medium {
  ServerMediaSubsession* fSubsessionsHead;              -----------看到没,双链表,由此看出一个ServerMediaSession包含了多个ServerMediaSubsession
  ServerMediaSubsession* fSubsessionsTail;              ServerMediaSubsession是纯虚,抽象类
virtual void startStream(unsigned clientSessionId, void* streamToken, virtual void startStream(unsigned clientSessionId, void* streamToken,---)---------------是不是还没看懂,不要紧,接着看下面的主题


}

A 'ServerMediaSubsession' object that represents an existing
// 'RTPSink', rather than one that creates new 'RTPSink's on demand
class ServerMediaSubsession:
{
virtual void getStreamParameters(unsigned clientSessionId, // in
.................
...................
) = 0;
virtual void startStream(unsigned clientSessionId, void* streamToken,
..................
..................
void* serverRequestAlternativeByteHandlerClientData) = 0;
}
private:
friend class ServerMediaSession;
friend class ServerMediaSubsessionIterator;
ServerMediaSubsession* fNext;

  unsigned fTrackNumber; // within an enclosing ServerMediaSession
char const* fTrackId;
}
class PassiveServerMediaSubsession: public ServerMediaSubsession
{
virtual char const* sdpLines();
virtual void getStreamParameters(unsigned clientSessionId,
.....................
.....................
void*& streamToken);

  virtual void startStream(unsigned clientSessionId, void* streamToken,
....................
....................
void* serverRequestAlternativeByteHandlerClientData);

private:
RTPSink& fRTPSink;
RTCPInstance* fRTCPInstance;
HashTable* fClientRTCPSourceRecords; // indexed by client session id; used to implement RTCP "RR" handling

 

ServerMediaSession类功能总结:ServerMediaSession 代表的是一个静态的流, 也就是可以从它里面获取一个流的各种信息

  1. static Boolean lookupByName(UsageEnvironment& env,char const* mediumName,ServerMediaSession*& resultSession);-------------------定义了查找函数,说明不止一个
  2. generateSDPDescription--------------------------------------------------------------------------------------------------------------------------涉及到SDP协议
  3. referenceCount-----------------------------------------------------------------------------------------------------------------------------------当ServerMediaSubsession为0,则撤销该类

ServerMediaSubsession类功能总结:

  1. virtual void startStream(unsigned clientSessionId, void* streamToken,..........)=0,------------------------------------------------------------定义了真正出发数据传输的函数接口
  2. virtual void pauseStream(unsigned clientSessionId, void* streamToken);
  3. class OnDemandServerMediaSubsession定义了startStream---------------------------------------------------------------------------------------------OnDemandServerMediaSubsession在哪初始化的?? 
友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内