锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

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

live555的建立RTP会话

void RTSPServer::RTSPClientSession::handleCmd_SETUP(
    char const* cseq,
    char const* urlPreSuffix,
    char const* urlSuffix,
    char const* fullRequestStr)
{

   for (unsigned i = 0; i < fNumStreamStates; ++i) {-----此处遍历ServerMediaSubsession,创立fStreamStates。每一个tracknum对应一个ServerMediaSubsession
            subsession = iter.next();
            fStreamStates[i].subsession = subsession;
            fStreamStates[i].tcpSocketNum = -1; // for now; may get set for RTP-over-TCP streaming
            fStreamStates[i].streamToken = NULL; // for now; it may be changed by the "getStreamParameters()" call that comes later
      }
    }
ive555 中有两个 streamstate,一个是类 StreamState ,一个是此处的结构 struct streamState 。 类 SteamState 就 是 streamToken , 而 struct streamState 中 保 存 了MediaSubsession (即 track) 和类 StreamState 的对应。类 StreamState 代表一个真正流动起来的数据流。这个数据流是从源流到 Sink 。客户端与服务端的一个 rtp 会话中,有两个数据流,服务端是从 XXXFileSouce 流到 RTPSink,而客户端则是从 RTPSource 流到 XXXFileSink 。建立数据流的过程就是把 Source 与 Sink 连接起来。为何不把 StreamToken 保存在 MediaSubsession 中呢?看起来在 struct streamState中是一个 MediaSubsession 对应一个 streamToken 呀? 因为 MediaSubsession 代表一个 track 的静态数据,它是可以被其它 rtp 会话重用的。比如不同的用户可能会连接到
同一个媒体的同一个 track 。所以 streamToken 与 MediaSubsession 独立存在,只是被 RTSPClientSession   
streamToken 的建立过程存在于函数 subsession->getStreamParameters()中,让我们看

getStreamParameters是定义在ServerMediaSubsession类中的纯虚函数,其实现在子类OnDemandServerMediaSubsession中。这个函数中将完成source,RTPSink的创建工作,并将其与客户端的映射关系保存下来。

void OnDemandServerMediaSubsession  
::getStreamParameters(unsigned clientSessionId,  .......)
{  
    /------------------------------------------------------------------------------------------------/创建一对groupsocks实例,分别用于传输RTP、RTCP  类 Groupsock:这个是放在单独的库 Groupsock 中。它封装了 socket 操作,增加了多
------------------------------------------------------------------------------------------------播放支持和一对多单播的功能.
  
    ------------------------------------------------------------------------------------------------//RTP、RTCP的端口号是相邻的,并且RTP端口号为偶数。初始端口fInitialPortNum = 6970,  
    ------------------------------------------------------------------------------------------------//这是OnDemandServerMediaSubsession构造函数的缺省参数  
  
      // Normal case: We're streaming RTP (over UDP or TCP).  Create a pair of  
      // groupsocks (RTP and RTCP), with adjacent port numbers (RTP port number even):  
      NoReuse dummy; // ensures that we skip over ports that are already in use  
      for (portNumBits serverPortNum = fInitialPortNum; ; serverPortNum += 2) {  
     struct in_addr dummyAddr; dummyAddr.s_addr = 0;  
     RTPSink* rtpSink = NULL;
    serverRTPPort = serverPortNum;  
    rtpGroupsock = new Groupsock(envir(), dummyAddr, serverRTPPort, 255);  
    serverRTCPPort = serverPortNum+1;  
    rtcpGroupsock = new Groupsock(envir(), dummyAddr, serverRTCPPort, 255);  

      
 ------------------------------------------------------------------------------------------------//创建RTPSink,与source类似,在处理DESCRIBE命令进行过,RTPsink到底起什么作用??继续往下看
      unsigned char rtpPayloadType = 96 + trackNumber()-1; // if dynamic  
      rtpSink = createNewRTPSink(rtpGroupsock, rtpPayloadType, mediaSource);  
      udpSink = NULL;  
    }  

    // Turn off the destinations for each groupsock.  They'll get set later  
    // (unless TCP is used instead):  
    if (rtpGroupsock != NULL) rtpGroupsock->removeAllDestinations();  
    if (rtcpGroupsock != NULL) rtcpGroupsock->removeAllDestinations();  
  
  
    ------------------------------------------------------------------------------------------------//重新配置发送RTP 的socket缓冲区大小  
    if (rtpGroupsock != NULL) {  
      // Try to use a big send buffer for RTP -  at least 0.1 second of  
      // specified bandwidth and at least 50 KB  
      unsigned rtpBufSize = streamBitrate * 25 / 2; // 1 kbps * 0.1 s = 12.5 bytes  
      if (rtpBufSize < 50 * 1024) rtpBufSize = 50 * 1024;  
      increaseSendBufferTo(envir(), rtpGroupsock->socketNum(), rtpBufSize); //这个函数在groupsock中定义  
    }  
  
  
    ---------------------------------------------------------------------------------//建立流的状态对像(stream token),其它包括sink、source、groupsock等的对应关系  
   ------------------------------------------------------------------------------ //注意,live555中定义了两个StreamState结构,这里的StreamState定义为一个类。在RTSPServer中,  
    //定义了一个内部结构体StreamState,其streamToken成员指向此处的StreamState实例  
    // Set up the state of the stream.  The stream will get started later:  
    streamToken = fLastStreamToken  ------------------------------------------------------------------//streamToken 里面包含了rtpsink ,serverRTCPPort,serverRTPPort,rtpGroupsock
      = new StreamState(*this, serverRTPPort, serverRTCPPort, rtpSink, udpSink,  
            streamBitrate, mediaSource,  
            rtpGroupsock, rtcpGroupsock);  
  }  
  
  
     ------------------------------------------------------------//这里定义了类Destinations来保存目的地址、RTP端口、RTCP端口,并将其与对应的clientSessionId保存到哈希表  
     -----------------------------------------------------------------------------//fDestinationsHashTable中,这个哈希表是定义在OnDemandServerMediaSubsession类中  
   ------------------------------------------------------------------------------------------------// Record these destinations as being for this client session id:  
  Destinations* destinations;  
  if (tcpSocketNum < 0) { // UDP  
    destinations = new Destinations(destinationAddr, clientRTPPort, clientRTCPPort);  
  } else { // TCP  
    destinations = new Destinations(tcpSocketNum, rtpChannelId, rtcpChannelId);  
  }  
  fDestinationsHashTable->Add((char const*)clientSessionId, destinations);  //---------------------------------------clientSessionId

RTPSink作用
class RTPSink: public MediaSink {
unsigned char rtpPayloadType() const { return fRTPPayloadType; }----------------------------------------------------------熟悉rtp协议的多知道这个和rtp协议参数紧密结合
unsigned rtpTimestampFrequency() const { return fTimestampFrequency; }
void setRTPTimestampFrequency(unsigned freq) {

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内