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

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

WBOY
WBOYOriginal
2016-06-07 15:37:422378browse

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

  1. JRTP传输:  
  2. 好了,下面是我写的使用JRTP进行发送H264数据包的例子,具体解释可以看注释。发送端也可以接收接收端发送过来的RTCP数据包。  
  3. #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;
  4.   
  5. bool CheckError(int rtperr);  
  6.   
  7.   
  8. class CRTPSender :  
  9.     public RTPSession  
  10. {  
  11. public:  
  12.     CRTPSender(void);  
  13.     ~CRTPSender(void);  
  14.   
  15. protected:  
  16.     void OnAPPPacket(RTCPAPPPacket *apppacket,const RTPTime &receivetime,const RTPAddress *senderaddress);  
  17.     void OnBYEPacket(RTPSourceData *srcdat);  
  18.     void OnBYETimeout(RTPSourceData *srcdat);  
  19. public:  
  20.     void SendH264Nalu(unsigned char* m_h264Buf,int buflen);  
  21.     void SetParamsForSendingH264();  
  22. };  
  23.   
  24.   
  25. bool CheckError(int rtperr)  
  26. {  
  27.     if (rtperr 
  28.     {  
  29.         std::cout"ERROR: "
  30.         return false;  
  31.     }  
  32.     return true;  
  33. }  
  34.   
  35.   
  36. CRTPSender::CRTPSender(void)  
  37. {  
  38. }  
  39.   
  40.   
  41. CRTPSender::~CRTPSender(void)  
  42. {  
  43. }  
  44.   
  45. void CRTPSender::OnAPPPacket(RTCPAPPPacket *apppacket,const RTPTime &receivetime,const RTPAddress *senderaddress)  
  46. {//收到RTCP APP数据  
  47.     std::cout"Got RTCP packet from: "
  48.     std::cout"Got RTCP subtype: "GetSubType()
  49.     std::cout"Got RTCP data: "char *)apppacket->GetAPPData()
  50.     return ;  
  51. }  
  52.   
  53. void CRTPSender::SendH264Nalu(unsigned char* m_h264Buf,int buflen)   
  54. {  
  55.     unsigned char *pSendbuf; //发送数据指针  
  56.     pSendbuf = m_h264Buf;  
  57.       
  58.     //去除前导码0x000001 或者0x00000001  
  59.     //if( 0x01 == m_h264Buf[2] )  
  60.     //{  
  61.     //  pSendbuf = &m_h264Buf[3];  
  62.     //  buflen -= 3;  
  63.     //}  
  64.     //else  
  65.     //{  
  66.     //  pSendbuf = &m_h264Buf[4];  
  67.     //  buflen -= 4;  
  68.     //}  
  69.       
  70.   
  71.     char sendbuf[1430];   //发送的数据缓冲  
  72.     memset(sendbuf,0,1430);  
  73.   
  74.     int status;    
  75.   
  76.     printf("send packet length %d \n",buflen);  
  77.   
  78.     if ( buflen 
  79.     {    
  80.         memcpy(sendbuf,pSendbuf,buflen);    
  81.         status = this->SendPacket((void *)sendbuf,buflen);  
  82.      
  83.         CheckError(status);  
  84.   
  85.     }    
  86.     else if(buflen > MAX_RTP_PKT_LENGTH)  
  87.     {  
  88.         //设置标志位Mark为0  
  89.         this->SetDefaultMark(false);  
  90.         //printf("buflen = %d\n",buflen);  
  91.         //得到该需要用多少长度为MAX_RTP_PKT_LENGTH字节的RTP包来发送  
  92.         int k=0,l=0;    
  93.         k = buflen / MAX_RTP_PKT_LENGTH;  
  94.         l = buflen % MAX_RTP_PKT_LENGTH;  
  95.         int t=0;//用指示当前发送的是第几个分片RTP包  
  96.   
  97.         char nalHeader = pSendbuf[0]; // NALU 头a?¤  
  98.         while( t 0 ) )    
  99.         {    
  100.             if( (0 == t ) || ( t//第一包到最后包的前一包  
  101.             {  
  102.                 /*sendbuf[0] = (nalHeader & 0x60)|28;   
  103.                 sendbuf[1] = (nalHeader & 0x1f); 
  104.                 if ( 0 == t ) 
  105.                 { 
  106.                     sendbuf[1] |= 0x80; 
  107.                 } 
  108.                 memcpy(sendbuf+2,&pSendbuf[t*MAX_RTP_PKT_LENGTH],MAX_RTP_PKT_LENGTH); 
  109.                 status = this->SendPacket((void *)sendbuf,MAX_RTP_PKT_LENGTH+2);*/  
  110.                 memcpy(sendbuf,&pSendbuf[t*MAX_RTP_PKT_LENGTH],MAX_RTP_PKT_LENGTH);  
  111.                 status = this->SendPacket((void *)sendbuf,MAX_RTP_PKT_LENGTH);  
  112.                 CheckError(status);  
  113.                 t++;  
  114.             }  
  115.             //最后一包  
  116.             else if( ( k==t && l>0 ) || ( t== (k-1) && l==0 ))  
  117.             {  
  118.                 //设置标志位Mark为1  
  119.                 this->SetDefaultMark(true);  
  120.   
  121.                 int iSendLen;  
  122.                 if ( l > 0)  
  123.                 {  
  124.                     iSendLen = buflen - t*MAX_RTP_PKT_LENGTH;  
  125.                 }  
  126.                 else  
  127.                     iSendLen = MAX_RTP_PKT_LENGTH;  
  128.   
  129.                 //sendbuf[0] = (nalHeader & 0x60)|28;    
  130.                 //sendbuf[1] = (nalHeader & 0x1f);  
  131.                 //sendbuf[1] |= 0x40;  
  132.   
  133.                 //memcpy(sendbuf+2,&pSendbuf[t*MAX_RTP_PKT_LENGTH],iSendLen);  
  134.                 //status = this->SendPacket((void *)sendbuf,iSendLen+2);  
  135.      
  136.                 memcpy(sendbuf,&pSendbuf[t*MAX_RTP_PKT_LENGTH],iSendLen);  
  137.                 status = this->SendPacket((void *)sendbuf,iSendLen);  
  138.   
  139.                 CheckError(status);  
  140.                 t++;  
  141.             }  
  142.         }  
  143.     }  
  144. }  
  145.   
  146.   
  147. void CRTPSender::SetParamsForSendingH264()  
  148. {  
  149.     this->SetDefaultPayloadType(H264);//设置传输类型  
  150.     this->SetDefaultMark(true);      //设置位  
  151.     this->SetTimestampUnit(1.0/9000.0); //设置采样间隔  
  152.     this->SetDefaultTimestampIncrement(3600);//设置时间戳增加间隔  
  153. }  
  154.   
  155. void CRTPSender::OnBYEPacket(RTPSourceData *srcdat)  
  156. {  
  157.   
  158. }  
  159.   
  160. void CRTPSender::OnBYETimeout(RTPSourceData *srcdat)  
  161. {  
  162.   
  163. }  
  164.   
  165.   
  166.   
  167. #define SSRC           100  
  168.   
  169. #define DEST_IP_STR   "192.168.1.252"  
  170. #define DEST_PORT     1234  
  171. #define BASE_PORT     2222  
  172. #include "RTPSender.h"  

  173. int iNal   = 0;  
  174. x264_nal_t* pNals = NULL;  
  175.   
  176.   
  177. void SetRTPParams(CRTPSender& sess,uint32_t destip,uint16_t destport,uint16_t baseport)  
  178. {  
  179.     int status;    
  180.     //RTP+RTCP库初始化SOCKET环境  
  181.     RTPUDPv4TransmissionParams transparams;  
  182.     RTPSessionParams sessparams;  
  183.     sessparams.SetOwnTimestampUnit(1.0/9000.0); //时间戳单位  
  184.     sessparams.SetAcceptOwnPackets(true);   //接收自己发送的数据包  
  185.     sessparams.SetUsePredefinedSSRC(true);  //设置使用预先定义的SSRC  
  186.     sessparams.SetPredefinedSSRC(SSRC);     //定义SSRC  
  187.      
  188.     transparams.SetPortbase(baseport);  
  189.   
  190.     status = sess.Create(sessparams,&transparams);    
  191.     CheckError(status);  
  192.   
  193.     destip = ntohl(destip);  
  194.     RTPIPv4Address addr(destip,destport);  
  195.     status = sess.AddDestination(addr);  
  196.     CheckError(status);  
  197.       
  198.     //为发送H264包设置参数  
  199.     //sess.SetParamsForSendingH264();  
  200.   
  201. }  
  202. bool InitSocket()  
  203. {  
  204.     int Error;  
  205.     WORD VersionRequested;  
  206.     WSADATA WsaData;  
  207.     VersionRequested=MAKEWORD(2,2);  
  208.     Error=WSAStartup(VersionRequested,&WsaData); //启动WinSock2  
  209.     if(Error!=0)  
  210.     {  
  211.         printf("Error:Start WinSock failed!\n");  
  212.         return false;  
  213.     }  
  214.     else  
  215.     {  
  216.         if(LOBYTE(WsaData.wVersion)!=2||HIBYTE(WsaData.wHighVersion)!=2)  
  217.         {  
  218.             printf("Error:The version is WinSock2!\n");  
  219.             WSACleanup();  
  220.             return false;  
  221.         }  
  222.   
  223.     }  
  224.     return true;  
  225. }  
  226.   
  227. void CloseSocket(CRTPSender sess)  
  228. {  
  229.     //发送一个BYE包离开会话最多等待秒钟超时则不发送  
  230.     sess.BYEDestroy(RTPTime(3,0),0,0);  
  231.     WSACleanup();  
  232. }  
  233.   
  234. int main(int argc, char** argv)  
  235. {  
  236.     InitSocket();  
  237.     CRTPSender sender;  
  238.     string destip_str = "127.0.0.1";  
  239.     uint32_t dest_ip = inet_addr(destip_str.c_str());             
  240.   
  241.     SetRTPParams(sender,dest_ip,DEST_PORT,BASE_PORT);  
  242.     sender.SetParamsForSendingH264();  
  243.   
  244.     //…x264设置参数等步骤,具体参见上篇博客  
  245.     for(int i = 0; i 
  246.     {  
  247.         //读取一帧  
  248.         read_frame_y4m(pPicIn,(hnd_t*)y4m_hnd,i);  
  249.         if( i ==0 )  
  250.             pPicIn->i_pts = i;  
  251.         else  
  252.             pPicIn->i_pts = i - 1;  
  253.           
  254.         //编码  
  255.         int frame_size = x264_encoder_encode(pX264Handle,&pNals,&iNal,pPicIn,pPicOut);  
  256.   
  257.         if(frame_size >0)  
  258.         {  
  259.               
  260.             for (int i = 0; i 
  261.             {//将编码数据写入文件t  
  262.                 //fwrite(pNals[i].p_payload, 1, pNals[i].i_payload, pFile);  
  263.                 //发送编码文件  
  264.                 sender.SendH264Nalu(pNals[i].p_payload,pNals[i].i_payload);  
  265.                 RTPTime::Wait(RTPTime(1,0));  
  266.             }  
  267.         }  
  268.     }  
  269.   
  270.      CloseSocket(sender);  
  271.     //一些清理工作…  
  272. }  
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn