1. 程式人生 > >使用jrtplib傳輸H.264視訊檔案(3)

使用jrtplib傳輸H.264視訊檔案(3)

介紹如何傳送h264,下面我們介紹下如何接收h264檔案。

其中主要關注的就是被拆分的資料包的重組,下面的程式碼中有詳盡的註釋。

  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. public:  
  8.     CThreadSafeArray m_ReceiveArray;  
  9.     void InitBufferSize();  
  10. private:  
  11.     CVideoData* m_pVideoData;  
  12.     unsigned char m_buffer[BUFFER_SIZE];  
  13.     int m_current_size;  
  14. };  
  15. void CRTPReceiver::InitBufferSize()  
  16. {  
  17.     m_ReceiveArray.SetMemberSize(BUFFER_SIZE);  
  18.     m_pVideoData = new CVideoData();  
  19.     memset(m_buffer,0,BUFFER_SIZE);  
  20.     m_current_size = 0;  
  21. }  
  22. void CRTPReceiver::OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,const RTPAddress *senderaddress)  
  23. {  
  24.     //std::cout<<"Got RTCP packet from: "<<senderaddress<<std::endl;
  25. }  
  26. void CRTPReceiver::OnPollThreadStep()  
  27. {  
  28.     BeginDataAccess();  
  29.     // check incoming packets
  30.     if (GotoFirstSourceWithData())  
  31.     {  
  32.         do
  33.         {  
  34.             RTPPacket *pack;  
  35.             RTPSourceData *srcdat;  
  36.             srcdat = GetCurrentSourceInfo();  
  37.             while ((pack = GetNextPacket()) != NULL)  
  38.             {  
  39.                 ProcessRTPPacket(*srcdat,*pack);  
  40.                 DeletePacket(pack);  
  41.             }  
  42.         } while (GotoNextSourceWithData());  
  43.     }  
  44.     EndDataAccess();  
  45. }  
  46. void CRTPReceiver::ProcessRTPPacket(const RTPSourceData &srcdat,const RTPPacket &rtppack)  
  47. {  
  48.     // You can inspect the packet and the source's info here
  49.     //std::cout<<"Packet type: "<<rtppack.GetPayloadType()<<std::endl;
  50.     //std::cout<<"Packet says: "<<(char *)rtppack.GetPayloadData()<<std::endl;
  51.     //test RTCP packet
  52.     /*int status = this->SendRTCPAPPPacket(0,(uint8_t*)&("123"),(void*)&("hel"),4); 
  53.     checkerror(status);*/
  54.     if(rtppack.GetPayloadType() == H264)  
  55.     {  
  56.         //std::cout<<"Got H264 packet:êo " << rtppack.GetExtendedSequenceNumber() << " from SSRC " << srcdat.GetSSRC() <<std::endl;
  57.         if(rtppack.HasMarker())//如果是最後一包則進行組包
  58.         {  
  59.             m_pVideoData->m_lLength = m_current_size + rtppack.GetPayloadLength();//得到資料包總的長度
  60.             memcpy(m_pVideoData->m_pBuffer,m_buffer,m_current_size);  
  61.             memcpy(m_pVideoData->m_pBuffer + m_current_size ,rtppack.GetPayloadData(),rtppack.GetPayloadLength());  
  62.             m_ReceiveArray.Add(m_pVideoData);//新增到接收佇列
  63.             memset(m_buffer,0,m_current_size);//清空快取,為下次做準備
  64.             m_current_size = 0;  
  65.         }  
  66.         else//放入緩衝區,在此必須確保有序
  67.         {  
  68.             unsigned char* p = rtppack.GetPayloadData();  
  69.             memcpy(m_buffer + m_current_size,rtppack.GetPayloadData(),rtppack.GetPayloadLength());  
  70.             m_current_size += rtppack.GetPayloadLength();  
  71.         }  
  72.     }  
  73. }  
  74. void StartReceive()  
  75. {  
  76.     /*CRTPReceiver sess;*/
  77.     sess.InitBufferSize();  
  78.     std::string ipstr;  
  79.     int status;  
  80.     // Now, we'll create a RTP session, set the destination
  81.     // and poll for incoming data.
  82.     RTPUDPv4TransmissionParams transparams;  
  83.     RTPSessionParams sessparams;  
  84.     // IMPORTANT: The local timestamp unit MUST be set, otherwise
  85.     //            RTCP Sender Report info will be calculated wrong
  86.     // In this case, we'll be just use 9000 samples per second.
  87.     sessparams.SetOwnTimestampUnit(1.0/9000.0);       
  88.     transparams.SetPortbase(PORT_BASE);  
  89.     status = sess.Create(sessparams,&transparams);    
  90.     checkerror(status);  
  91.     uint32_t dst_ip = inet_addr(DST_IP);  
  92.     dst_ip = ntohl(dst_ip);  
  93.     RTPIPv4Address addr(dst_ip,DST_PORT);  
  94.     status = sess.AddDestination(addr);  
  95.     checkerror(status);  
  96. }  
  97. int main(int argc, char* argv[])  
  98. {  
  99.     WSADATA dat;  
  100.     WSAStartup(MAKEWORD(2,2),&dat);  
  101.     StartReceive();  
  102.     RTPTime::Wait(RTPTime(3,0));  
  103.     return 0;  
  104. }  
至此,使用jrtplib傳輸h264全部完成。