jrtplib V3.11.1 收包流程

来源:互联网 发布:ubuntu 花屏 编辑:程序博客网 时间:2024/06/09 19:24

       最近在看 jrtplib的收包流程,看了这篇文章 jrtplib接收数据包流程 ,只是用的库老了点 V3.7 的,写的也太长了,不够简练,于是自己写一份

         V3.11.1的简练点的收包流程说明,捡重点,无关的流程略过。


RTP包的接收入口函数
int RTPSession::Poll()
{
   if ((status = rtptrans->Poll()) < 0)    // 流程一, 默认调用 RTPUDPv4Transmitter::Poll() // 处理收到的buffer,转为元数据,存入容器


    return ProcessPolledData();          // 流程二,将元数据解析为 RTP或RTCP包,分别处理之
}


     ————————————— 流程(一) 的剖析  ————————————–

说明: rtptrans是RTPSession类的成员变量,默认是Rtpudpv4transmitter类,它实现了rtp包以及rtcp包的收发工作

步骤1,分别从 rtpsock 和 rtcpsock 收数据
int RTPUDPv4Transmitter::Poll()
{

status = PollSocket(true); // poll RTP socket

  if (rtpsock != rtcpsock) // no need to poll twice when multiplexing
   {
        if (status >= 0)
        status = PollSocket(false); // poll RTCP socket
  }
}


步骤2
int RTPUDPv4Transmitter::PollSocket(bool rtp)
{
// 收rtp或rtcp包
recvlen = recvfrom(sock,packetbuffer,RTPUDPV4TRANS_MAXPACKSIZE,0,(struct sockaddr *)&srcaddr,&fromlen);

// 收到的buffer构建元数据
pack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPRAWPACKET)RTPRawPacket(datacopy,recvlen,addr,curtime,rtp,GetMemoryManager());

// 将元数据存入队列
rawpacketlist.push_back(pack);

}


————————————— 流程(二) 的剖析  ————————————–
步骤1
int RTPSession::ProcessPolledData()
{

 while ((rawpack = rtptrans->GetNextPacket()) != 0)
 {
    //内部遍历并解析元数据,得到RTPPacket包
    if ((status = sources.ProcessRawPacket(rawpack,rtptrans,acceptownpackets)) < 0)

 }
     
   // 下面是发送rtcp相关的,没研究过
   status = rtcpbuilder.BuildNextPacket(&pack)

   Status=rtptrans->SendRTCPData(pack->GetCompoundPacketData(),pack->GetCompoundPacketLength()) //发送rtcp包

}


步骤2,内部解析元数据,判断是RTP还是RTCP包,然后分别处理
int RTPSources::ProcessRawPacket(RTPRawPacket *rawpack )
{
     步骤2.1 解析源数据, 得到RTPPacket包,如果你测试发送的是字符串,就可以看到payload属性的值了"1234456789AB"
    rtppack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPPACKET) RTPPacket(*rawpack,GetMemoryManager());


    步骤2.2  处理RTP包
    if ((status = ProcessRTPPacket(rtppack,rawpack->GetReceiveTime(),0,&stored)) < 0)


    步骤2.3  处理RTCP包
    status = ProcessRTCPCompoundPacket(&rtcpcomppack,rawpack->GetReceiveTime(),0);
    {   
      在函数内部,根据遍历RTCP包,根据包类型分别处理
        SR, /**< An RTCP sender report. */
                RR, /**< An RTCP receiver report. */
                SDES, /**< An RTCP source description packet. */
       BYE, /**< An RTCP bye packet. */
                APP, /**< An RTCP packet containing application specific data. */
                Unknown /**< The type of RTCP packet was not recognized. */
    }

    // 注意把元数据解析成RTPpacket的函数如下
    int RTPPacket::ParseRawPacket(RTPRawPacket &rawpack)

}




步骤2.2
int RTPSources::ProcessRTPPacket(
{
   // 虚函数,什么都没干,可扩展
   OnRTPPacket(rtppack,receivetime,senderaddress);


   // 步骤2.2.1,构建 RTPInternalSourceData对象
   if ((status = ObtainSourceDataInstance(ssrc,&srcdat,&created)) < 0)


   // 步骤2.2.2, 内部调用 RTPInternalSourceData::ProcessRTPPacket( ) 函数来处理 .  RTP数据收包处理到此结束

   if ((status = srcdat->ProcessRTPPacket(rtppack,receivetime,stored,this)) < 0)
   {
        //内部按序列号用容器存储,最多存32个
packetlist.push_front(rtppack);
      packetlist.insert(it,rtppack);
   }


   // 步骤2.2.3, 内部循环处理CSRC数组,没研究过
   for (i = 0 ; i < num ; i++)

   {
      if ((status = ObtainSourceDataInstance(CSRCs[i],&csrcdat,&createdcsrc)) < 0)
   }

}



 ok,到此RTPSession收RTP包后存入队列,收包流程就结束了,接下来就是处理这些收到的包了,官方示例如下:


      sess.BeginDataAccess(); //同步锁

// check incoming packets
// 开始遍历参与者中第一个有RTP数据的流,如果找到了,就返回tree,否则返回false。
//在接收数据时我们常用的是这套函数,因为如果没有数据要来都没用 
if (sess.GotoFirstSourceWithData())   
{   
//实际上是双层嵌套循环,第一层先遍历内部的RTPInternalSourceData对象,rcdat = sourcelist.GetCurrentElement(); 
do
{
RTPPacket *pack;
// 再遍历该RTPInternalSourceData对象内部的 RTPpacket列表
while ((pack = sess.GetNextPacket()) != NULL)
{
// You can examine the data here

// for test
char pBuffer[100] ={0};
memcpy(pBuffer,pack->GetPayloadData(),pack->GetPayloadLength());
printf("Got packet -->%s \n",pBuffer); // 界面打印收到的字符串

// we don't longer need the packet, so
// we'll delete it
sess.DeletePacket(pack);
}
} while (sess.GotoNextSourceWithData());
}

sess.EndDataAccess();  






原创粉丝点击