RTP/RTCP 视频数据传输 (续)

原创 2006年06月22日 14:45:00

      直接进入正题,经过JPEG压缩后的数据时通过RTP/RTCP协议传输到网络上去的,本课题使用的是Jrtplib的RTP/RTCP协议栈,首先在网上获取Jrtplib包的源码,解压缩配置编译安装,没有bugs就ok了

      在源码包里面有好几个examples,都可以借鉴。在设置Server端的时候,与TCP/IP协议不一样,首先在初始化打开的Session的时候,设置一个baseport端口,同时设置Client端的ip和port,然后再根据视频采样的频率设置时间戳,具体的设置函数都可以在examples中找到并且能很好的复用。

     这里讲一下发送和接收的代码,发送和接收都是通过线程来实现的:

     发送:

      ret = Send_rtppacket((unsigned char*)videoIn.ptframe[frameout],sizeof(struct frame_t)+headerframe->size);

      在发送线程函数中直接发送ptframe[]指针指向的数据,数据大小为sizeof(struct frame_t)+headerframe->size,包含了该frame的数据,以及对该frame参数描述的数据结构。

    int Send_rtppacket(unsigned char* framepointer,int framelength)
{
 int done = 0;
 int flage;
 int sendbyte = 0;
 int n;
 do{
 if(framelength > PacketMaxsize)   //设置packetmaxsize: 1400 ,oversize情况下就要分割传输
  flage = 0;
  else flage =1;
 
 if(flage = 1)
 { 
  n = session.SendPacket(framepointer,framelength,26,1,1000);   //发送函数 第四个参数决定是否是该frame最后

                                                                                                                         小于1400的数据
  done = 1;                                                                                                    //如果是 标示完成
  sendbyte = framelength;
 }else{
  n = session.SendPacket(framepointer,PacketMaxsize,26,0,1000);
  framepointer = framepointer + PacketMaxsize ;                               //update发送指针
  framelength = framelength - PacketMaxsize ;
  sendbyte = sendbyte + PacketMaxsize;
  }
  if(n<0)
  { return -1;}
  RTPTime::Wait (delay);
 }while(!done);
 return  sendbyte;
}

接收:

            do {
      // 检索RTP数据源
       sess.BeginDataAccess();
      if (sess.GotoFirstSourceWithData() ) {
        do {
          RTPPacket* packet;
   RTPSourceData *srcdata;
          // 获取RTP数据报
          packetflage =0;
         recvlength =0;     //初始化接收数据 以及数据接收标示
     while ((packet = sess.GetNextPacket()) != NULL && packetflage==0) {  //标示为零 接收同一packet的剩余数据
             //printf("Got packet !/n");
       
             if(processpacket(*srcdata,*packet)){
             packetflage = 1; //processpacket() 返回1 已经接受到所有的packet 可以调用解码,SDL显示
           //printf("Debug...packetflage: %d/n",packetflage);
    jpegsize = readjpeg(&buf,headerframe);
             //printf("Debug...jpegsize: %d/n",jpegsize);
             if(!jpegsize && videoOk)
     close_sdlvideo();
      if(jpegsize && !videoOk)
             {
               init_sdlvideo();  
      pscreen = SDL_SetVideoMode (owidth, oheight, bpp * 8,SDL_DOUBLEBUF | SDL_SWSURFACE);
      p=(unsigned char*)pscreen->pixels;
    }
  
      if(jpegsize && videoOk)
      {
             jpeg_decode(&picture,buf,&width,&height);
    resize (p,picture,owidth,oheight,width,height) ;
    SDL_WM_SetCaption (titre, NULL);
    SDL_Flip (pscreen); 
            }
            if(SDL_PollEvent (&sdlevent)<0) goto error;
          }  
            else packetflage =0;   //返回0,packet还没接受完 继续sess.GetNextPacket()
           
  delete packet;  // 删除RTP数据报
        }
      } while (sess.GotoNextSourceWithData());   //接收另一个packet
    }
     sess.EndDataAccess();
      // 接受RTP数据
     status = sess.Poll();
     checkerror(status);
     RTPTime::Wait(RTPTime(1,0));
  } while(1);

int processpacket(const RTPSourceData &srcdat,const RTPPacket &rtppack)
{
 unsigned char* payloadpointer = rtppack.GetPayloadData();    //接收该数据包数据
     bool packetmarker = rtppack.HasMarker();   //察看部否是已经传完该数据包
     int flage =1;
        //printf("Debug..........1/n");
 if(!packetmarker)   //未传完数据包
 {
  memcpy(recvpointer+recvoffset,payloadpointer,rtppack.GetPayloadLength());
  recvlength += rtppack.GetPayloadLength();
      recvoffset += rtppack.GetPayloadLength();  //更新接收数据保存的指针
 // printf("Debug..........2/n");
  flage = 0;   //标示接受位 继续执行sess.GetNextPacket()
     }
 else{
  memcpy(recvpointer +recvoffset,payloadpointer,rtppack.GetPayloadLength());
  
  recvlength += rtppack.GetPayloadLength();
  recvoffset = 0;                     //传完,初始化
 // printf("Debug..........3/n");
 }
 return flage;
}

 

小结:

      RTP/RTCP传输数据的流程:

Server端:

       发送定长的数据报到Client端,发送的时候是分批以packet的形式发送到Client,就是说发送一个数据包需要几次packet发送来完成。发送成功以后发送下一个数据包,始终调用函数:session.SendPacket();

Client端:

      依次循环调用sess.GetNextPacket()来接收某一数据包的packet数据,packet的到来不是按顺序到来的,完全接收到数据包所用的packets以后,RTP库在根据时间戳对接受的packet重新排序生成最终的数据包。接收数据包成功后,调用sess.GotoNextSourceWithData()开始接收下一个数据包

     

自适应流媒体传输(三)——和TS格式说再见

如果你读过MPEG-DASH(23009 - Dynamic Adaptive Streaming over HTTP)的spec,一定能感觉到整个标准对fMP4这种格式的强烈倾向性。HLS倒是一直喜...

使用CMake编译跨平台静态库

使用CMake编译跨平台静态库 转载于HTTP://4GAMERS.CN/BLOG/2014/09/01/HOW-TO-USE-CMAKE-TO-COMPILE-STATIC-LIBRARY/ ...
  • or7rccl
  • or7rccl
  • 2017年03月17日 13:38
  • 422

RTP/RTCP 视频数据传输

直接进入正题,经过JPEG压缩后的数据时通过RTP/RTCP协议传输到网络上去的,本课题使用的是Jrtplib的RTP/RTCP协议栈,首先在网上获取Jrtplib包的源码,解压缩配置编译安装,没有b...
  • yuyin86
  • yuyin86
  • 2011年07月08日 16:32
  • 617

RTP/RTCP 视频数据传输

直接进入正题,经过JPEG压缩后的数据时通过RTP/RTCP协议传输到网络上去的,本课题使用的是Jrtplib的RTP/RTCP协议栈,首先在网上获取Jrtplib包的源码,解压缩配置编译安装,没有b...

RTP/RTCP视频数据传输

直接进入正题,经过JPEG压缩后的数据时通过RTP/RTCP协议传输到网络上去的,本课题使用的是Jrtplib的RTP/RTCP协议栈,首先在网上获取Jrtplib包的源码,解压缩配置编译安装,没有b...
  • emalwb
  • emalwb
  • 2013年12月30日 14:31
  • 386

RTP实时音视频数据传输,发送端和接收端

1.项目前期工作(配置好环境) 点击打开链接 2.发送端文件编写(见下面的send.cpp) 3.接收端文件编写(见下面的receive.cpp) 4.编译文件 (1)发送端     ...

音视频开发——流媒体数据传输RTP(三)

实时传送协议(Real-time Transport Protocol或简写RTP,也可以写成RTTP)是一个网络传输协议。 关于RTP协议的详细介绍,可以参考这篇文章:RTP协议介绍:http://...

视频流传输协议RTP/RTCP/RTSP/HTTP的区别

用一句简单的话总结:RTSP发起/终结流媒体、RTP传输流媒体数据 、RTCP对RTP进行控制,同步。 之所以以前对这几个有点分不清,是因为CTC标准里没有对RTCP进行要求,因此在标准RTSP的代...

网络视频传输协议--RTP/RTCP/RTSP/SIP/SDP 之间关系

RTP/RTCP/RTSP/SIP/SDP 关系 1、 RTP Real-time Transport Protocol,是用于Internet上针对多媒体数据流的一种传输层协议。RTP协议详细说...
  • xdwyyan
  • xdwyyan
  • 2014年12月04日 11:06
  • 2891
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RTP/RTCP 视频数据传输 (续)
举报原因:
原因补充:

(最多只允许输入30个字)