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

转自:http://blog.csdn.net/liushu1231/article/details/9203643

本文所有内容均为原创,转载请注明出处!

介绍如何发送h264,下面我们介绍下如何接收h264文件。

其中主要关注的就是被拆分的数据包的重组,下面的代码中有详尽的注释。

[cpp]   view plain copy
  1. class CRTPReceiver : public RTPSession  
  2. {  
  3. protected:  
  4.     void OnPollThreadStep();  
  5.     void ProcessRTPPacket(const RTPSourceData &srcdat,const RTPPacket &rtppack);  
  6.     void OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,const RTPAddress *senderaddress);  
  7.       
  8. public:  
  9.     CThreadSafeArray m_ReceiveArray;  
  10.     void InitBufferSize();  
  11.   
  12. private:  
  13.     CVideoData* m_pVideoData;  
  14.     unsigned char m_buffer[BUFFER_SIZE];  
  15.     int m_current_size;  
  16. };  
  17.   
  18. void CRTPReceiver::InitBufferSize()  
  19. {  
  20.     m_ReceiveArray.SetMemberSize(BUFFER_SIZE);  
  21.     m_pVideoData = new CVideoData();  
  22.     memset(m_buffer,0,BUFFER_SIZE);  
  23.     m_current_size = 0;  
  24. }  
  25.   
  26. void CRTPReceiver::OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,const RTPAddress *senderaddress)  
  27. {  
  28.     //std::cout<<"Got RTCP packet from: "<<senderaddress<<std::endl;  
  29. }  
  30.   
  31.   
  32. void CRTPReceiver::OnPollThreadStep()  
  33. {  
  34.     BeginDataAccess();  
  35.           
  36.     // check incoming packets  
  37.     if (GotoFirstSourceWithData())  
  38.     {  
  39.         do  
  40.         {  
  41.             RTPPacket *pack;  
  42.             RTPSourceData *srcdat;  
  43.               
  44.             srcdat = GetCurrentSourceInfo();  
  45.               
  46.             while ((pack = GetNextPacket()) != NULL)  
  47.             {  
  48.                 ProcessRTPPacket(*srcdat,*pack);  
  49.                 DeletePacket(pack);  
  50.             }  
  51.         } while (GotoNextSourceWithData());  
  52.     }  
  53.           
  54.     EndDataAccess();  
  55. }  
  56.   
  57. void CRTPReceiver::ProcessRTPPacket(const RTPSourceData &srcdat,const RTPPacket &rtppack)  
  58. {  
  59.     // You can inspect the packet and the source's info here  
  60.     //std::cout<<"Packet type: "<<rtppack.GetPayloadType()<<std::endl;  
  61.     //std::cout<<"Packet says: "<<(char *)rtppack.GetPayloadData()<<std::endl;  
  62.     //test RTCP packet  
  63.     /*int status = this->SendRTCPAPPPacket(0,(uint8_t*)&("123"),(void*)&("hel"),4); 
  64.     checkerror(status);*/  
  65.   
  66.     if(rtppack.GetPayloadType() == H264)  
  67.     {  
  68.         //std::cout<<"Got H264 packet:êo " << rtppack.GetExtendedSequenceNumber() << " from SSRC " << srcdat.GetSSRC() <<std::endl;  
  69.         if(rtppack.HasMarker())//如果是最后一包则进行组包  
  70.         {  
  71.             m_pVideoData->m_lLength = m_current_size + rtppack.GetPayloadLength();//得到数据包总的长度  
  72.             memcpy(m_pVideoData->m_pBuffer,m_buffer,m_current_size);  
  73.             memcpy(m_pVideoData->m_pBuffer + m_current_size ,rtppack.GetPayloadData(),rtppack.GetPayloadLength());  
  74.               
  75.             m_ReceiveArray.Add(m_pVideoData);//添加到接收队列  
  76.   
  77.             memset(m_buffer,0,m_current_size);//清空缓存,为下次做准备  
  78.             m_current_size = 0;  
  79.         }  
  80.         else//放入缓冲区,在此必须确保有序  
  81.         {  
  82.             unsigned char* p = rtppack.GetPayloadData();  
  83.   
  84.   
  85.             memcpy(m_buffer + m_current_size,rtppack.GetPayloadData(),rtppack.GetPayloadLength());  
  86.             m_current_size += rtppack.GetPayloadLength();  
  87.         }  
  88.     }  
  89.   
  90. }  
  91.   
  92.   
  93. void StartReceive()  
  94. {  
  95.     /*CRTPReceiver sess;*/  
  96.     sess.InitBufferSize();  
  97.     std::string ipstr;  
  98.     int status;  
  99.   
  100.     // Now, we'll create a RTP session, set the destination  
  101.     // and poll for incoming data.  
  102.     RTPUDPv4TransmissionParams transparams;  
  103.     RTPSessionParams sessparams;  
  104.       
  105.     // IMPORTANT: The local timestamp unit MUST be set, otherwise  
  106.     //            RTCP Sender Report info will be calculated wrong  
  107.     // In this case, we'll be just use 9000 samples per second.  
  108.     sessparams.SetOwnTimestampUnit(1.0/9000.0);       
  109.       
  110.     transparams.SetPortbase(PORT_BASE);  
  111.     status = sess.Create(sessparams,&transparams);    
  112.     checkerror(status);  
  113.   
  114.     uint32_t dst_ip = inet_addr(DST_IP);  
  115.     dst_ip = ntohl(dst_ip);  
  116.     RTPIPv4Address addr(dst_ip,DST_PORT);  
  117.     status = sess.AddDestination(addr);  
  118.       
  119.     checkerror(status);  
  120. }  
  121.   
  122. int main(int argc, char* argv[])  
  123. {  
  124.     WSADATA dat;  
  125.     WSAStartup(MAKEWORD(2,2),&dat);  
  126.     StartReceive();  
  127.     RTPTime::Wait(RTPTime(3,0));  
  128.     return 0;  
  129. }  
至此,使用jrtplib传输h264全部完成。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用jrtplib发送PS流的步骤如下: 1. 初始化jrtplib库并创建一个RTPSession实例。 2. 设置RTPSession的传输协议类型为PS。 3. 设置RTPSession的传输模式为推送模式。 4. 设置RTPSession的远程地址和端口号。 5. 打开RTPSession。 6. 读取PS文件并将其分成小的NAL单元。 7. 将NAL单元打包成RTP包并发送到远程地址。 8. 关闭RTPSession。 代码示例: ```c++ #include <jrtplib3/rtpsession.h> #include <jrtplib3/rtpudpv4transmitter.h> #include <jrtplib3/rtpipv4address.h> #include <jrtplib3/rtptimeutilities.h> #include <iostream> #include <fstream> using namespace jrtplib; using namespace std; int main(int argc, char* argv[]) { RTPSession session; RTPUDPv4TransmissionParams transparams; RTPSessionParams sessparams; sessparams.SetOwnTimestampUnit(1.0/90000.0); transparams.SetPortbase(8000); int status = session.Create(sessparams,&transparams); if (status < 0) { cerr << "ERROR: " << RTPGetErrorString(status) << endl; return -1; } RTPIPv4Address addr("192.168.1.100", 9000); status = session.AddDestination(addr); if (status < 0) { cerr << "ERROR: " << RTPGetErrorString(status) << endl; return -1; } session.SetDefaultPayloadType(96); session.SetDefaultMark(false); session.SetTimestampUnit(1.0/90000.0); session.SetDefaultTimestampIncrement(3600); status = session.InitSend(); if (status < 0) { cerr << "ERROR: " << RTPGetErrorString(status) << endl; return -1; } ifstream fin("test.ps", ios::binary); if (!fin.is_open()) { cerr << "ERROR: cannot open file" << endl; return -1; } char nal[1024]; int nal_len = 0; while (!fin.eof()) { fin.read(nal + nal_len, 1024 - nal_len); nal_len += fin.gcount(); char* p = nal; while (nal_len > 0) { int len = 0; while (len < nal_len && !(p[len] == 0x00 && p[len+1] == 0x00 && p[len+2] == 0x01)) len++; if (len == nal_len) { break; } len += 3; RTPTime delay(0.020); session.SendPacket((void*)p, len, 96, false, delay); p += len; nal_len -= len; } } fin.close(); session.BYEDestroy(RTPTime(10,0),0,0); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值