您好,欢迎访问一九零五行业门户网

使用jrtplib(RTP)传输H.264视频文件(2)

http://blog.csdn.net/liushu1231/article/details/9203593 [cpp] view plaincopy jrtp传输: 好了,下面是我写的使用jrtp进行发送h264数据包的例子,具体解释可以看注释。发送端也可以接收接收端发送过来的rtcp数据包。 #define win32 #define debug #defin
http://blog.csdn.net/liushu1231/article/details/9203593
[cpp] view plaincopy
jrtp传输:  好了,下面是我写的使用jrtp进行发送h264数据包的例子,具体解释可以看注释。发送端也可以接收接收端发送过来的rtcp数据包。  #define win32
#define debug
#define max_rtp_pkt_length 1360  
#define h264               96
#include rtpsession.h
#include rtpudpv4transmitter.h
#include rtpipv4address.h
#include rtpsessionparams.h
#include rtperrors.h
#include rtcpapppacket.h
#ifndef win32
#include
#include
#else
#include
#endif // win32
#include
#include
#include
#include
#include
extern c
{
#include x264.h
#include x264_config.h
};
using namespace jrtplib;
using namespace std;  bool checkerror(int rtperr);      class crtpsender :      public rtpsession  {  public:      crtpsender(void);      ~crtpsender(void);    protected:      void onapppacket(rtcpapppacket *apppacket,const rtptime &receivetime,const rtpaddress *senderaddress);      void onbyepacket(rtpsourcedata *srcdat);      void onbyetimeout(rtpsourcedata *srcdat);  public:      void sendh264nalu(unsigned char* m_h264buf,int buflen);      void setparamsforsendingh264();  };      bool checkerror(int rtperr)  {      if (rtperr     {          std::couterror:         return false;      }      return true;  }      crtpsender::crtpsender(void)  {  }      crtpsender::~crtpsender(void)  {  }    void crtpsender::onapppacket(rtcpapppacket *apppacket,const rtptime &receivetime,const rtpaddress *senderaddress)  {//收到rtcp app数据      std::coutgot rtcp packet from:     std::coutgot rtcp subtype: getsubtype()    std::coutgot rtcp data: char *)apppacket->getappdata()    return ;  }    void crtpsender::sendh264nalu(unsigned char* m_h264buf,int buflen)   {      unsigned char *psendbuf; //发送数据指针      psendbuf = m_h264buf;            //去除前导码0x000001 或者0x00000001      //if( 0x01 == m_h264buf[2] )      //{      //  psendbuf = &m_h264buf[3];      //  buflen -= 3;      //}      //else      //{      //  psendbuf = &m_h264buf[4];      //  buflen -= 4;      //}              char sendbuf[1430];   //发送的数据缓冲      memset(sendbuf,0,1430);        int status;          printf(send packet length %d \n,buflen);        if ( buflen     {            memcpy(sendbuf,psendbuf,buflen);            status = this->sendpacket((void *)sendbuf,buflen);               checkerror(status);        }        else if(buflen > max_rtp_pkt_length)      {          //设置标志位mark为0          this->setdefaultmark(false);          //printf(buflen = %d\n,buflen);          //得到该需要用多少长度为max_rtp_pkt_length字节的rtp包来发送          int k=0,l=0;            k = buflen / max_rtp_pkt_length;          l = buflen % max_rtp_pkt_length;          int t=0;//用指示当前发送的是第几个分片rtp包            char nalheader = psendbuf[0]; // nalu 头a?¤          while( t 0 ) )            {                if( (0 == t ) || ( t//第一包到最后包的前一包              {                  /*sendbuf[0] = (nalheader & 0x60)|28;                   sendbuf[1] = (nalheader & 0x1f);                 if ( 0 == t )                 {                     sendbuf[1] |= 0x80;                 }                 memcpy(sendbuf+2,&psendbuf[t*max_rtp_pkt_length],max_rtp_pkt_length);                 status = this->sendpacket((void *)sendbuf,max_rtp_pkt_length+2);*/                  memcpy(sendbuf,&psendbuf[t*max_rtp_pkt_length],max_rtp_pkt_length);                  status = this->sendpacket((void *)sendbuf,max_rtp_pkt_length);                  checkerror(status);                  t++;              }              //最后一包              else if( ( k==t && l>0 ) || ( t== (k-1) && l==0 ))              {                  //设置标志位mark为1                  this->setdefaultmark(true);                    int isendlen;                  if ( l > 0)                  {                      isendlen = buflen - t*max_rtp_pkt_length;                  }                  else                      isendlen = max_rtp_pkt_length;                    //sendbuf[0] = (nalheader & 0x60)|28;                    //sendbuf[1] = (nalheader & 0x1f);                  //sendbuf[1] |= 0x40;                    //memcpy(sendbuf+2,&psendbuf[t*max_rtp_pkt_length],isendlen);                  //status = this->sendpacket((void *)sendbuf,isendlen+2);                       memcpy(sendbuf,&psendbuf[t*max_rtp_pkt_length],isendlen);                  status = this->sendpacket((void *)sendbuf,isendlen);                    checkerror(status);                  t++;              }          }      }  }      void crtpsender::setparamsforsendingh264()  {      this->setdefaultpayloadtype(h264);//设置传输类型      this->setdefaultmark(true);      //设置位      this->settimestampunit(1.0/9000.0); //设置采样间隔      this->setdefaulttimestampincrement(3600);//设置时间戳增加间隔  }    void crtpsender::onbyepacket(rtpsourcedata *srcdat)  {    }    void crtpsender::onbyetimeout(rtpsourcedata *srcdat)  {    }        #define ssrc           100    #define dest_ip_str   192.168.1.252  #define dest_port     1234  #define base_port     2222  #include rtpsender.h  
int inal   = 0;  x264_nal_t* pnals = null;      void setrtpparams(crtpsender& sess,uint32_t destip,uint16_t destport,uint16_t baseport)  {      int status;        //rtp+rtcp库初始化socket环境      rtpudpv4transmissionparams transparams;      rtpsessionparams sessparams;      sessparams.setowntimestampunit(1.0/9000.0); //时间戳单位      sessparams.setacceptownpackets(true);   //接收自己发送的数据包      sessparams.setusepredefinedssrc(true);  //设置使用预先定义的ssrc      sessparams.setpredefinedssrc(ssrc);     //定义ssrc           transparams.setportbase(baseport);        status = sess.create(sessparams,&transparams);        checkerror(status);        destip = ntohl(destip);      rtpipv4address addr(destip,destport);      status = sess.adddestination(addr);      checkerror(status);            //为发送h264包设置参数      //sess.setparamsforsendingh264();    }  bool initsocket()  {      int error;      word versionrequested;      wsadata wsadata;      versionrequested=makeword(2,2);      error=wsastartup(versionrequested,&wsadata); //启动winsock2      if(error!=0)      {          printf(error:start winsock failed!\n);          return false;      }      else      {          if(lobyte(wsadata.wversion)!=2||hibyte(wsadata.whighversion)!=2)          {              printf(error:the version is winsock2!\n);              wsacleanup();              return false;          }        }      return true;  }    void closesocket(crtpsender sess)  {      //发送一个bye包离开会话最多等待秒钟超时则不发送      sess.byedestroy(rtptime(3,0),0,0);      wsacleanup();  }    int main(int argc, char** argv)  {      initsocket();      crtpsender sender;      string destip_str = 127.0.0.1;      uint32_t dest_ip = inet_addr(destip_str.c_str());                   setrtpparams(sender,dest_ip,dest_port,base_port);      sender.setparamsforsendingh264();        //…x264设置参数等步骤,具体参见上篇博客      for(int i = 0; i     {          //读取一帧          read_frame_y4m(ppicin,(hnd_t*)y4m_hnd,i);          if( i ==0 )              ppicin->i_pts = i;          else              ppicin->i_pts = i - 1;                    //编码          int frame_size = x264_encoder_encode(px264handle,&pnals,&inal,ppicin,ppicout);            if(frame_size >0)          {                            for (int i = 0; i             {//将编码数据写入文件t                  //fwrite(pnals[i].p_payload, 1, pnals[i].i_payload, pfile);                  //发送编码文件                  sender.sendh264nalu(pnals[i].p_payload,pnals[i].i_payload);                  rtptime::wait(rtptime(1,0));              }          }      }         closesocket(sender);      //一些清理工作…  }
其它类似信息

推荐信息