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

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

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

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

[cpp] view plain copy
print ?
  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: ”<  
  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: ”<  
  61.     //std::cout<<”Packet says: ”<<(char *)rtppack.GetPayloadData()<  
  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() <  
  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. }  
class CRTPReceiver : public RTPSession
{
protected:
    void OnPollThreadStep();
    void ProcessRTPPacket(const RTPSourceData &srcdat,const RTPPacket &rtppack);
    void OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,const RTPAddress *senderaddress);

public:
    CThreadSafeArray m_ReceiveArray;
    void InitBufferSize();

private:
    CVideoData* m_pVideoData;
    unsigned char m_buffer[BUFFER_SIZE];
    int m_current_size;
};

void CRTPReceiver::InitBufferSize()
{
    m_ReceiveArray.SetMemberSize(BUFFER_SIZE);
    m_pVideoData = new CVideoData();
    memset(m_buffer,0,BUFFER_SIZE);
    m_current_size = 0;
}

void CRTPReceiver::OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,const RTPAddress *senderaddress)
{
    //std::cout<<"Got RTCP packet from: "<SendRTCPAPPPacket(0,(uint8_t*)&("123"),(void*)&("hel"),4);
    checkerror(status);*/

    if(rtppack.GetPayloadType() == H264)
    {
        //std::cout<<"Got H264 packet:êo " << rtppack.GetExtendedSequenceNumber() << " from SSRC " << srcdat.GetSSRC() <m_lLength = m_current_size + rtppack.GetPayloadLength();//得到数据包总的长度
            memcpy(m_pVideoData->m_pBuffer,m_buffer,m_current_size);
            memcpy(m_pVideoData->m_pBuffer + m_current_size ,rtppack.GetPayloadData(),rtppack.GetPayloadLength());

            m_ReceiveArray.Add(m_pVideoData);//添加到接收队列

            memset(m_buffer,0,m_current_size);//清空缓存,为下次做准备
            m_current_size = 0;
        }
        else//放入缓冲区,在此必须确保有序
        {
            unsigned char* p = rtppack.GetPayloadData();


            memcpy(m_buffer + m_current_size,rtppack.GetPayloadData(),rtppack.GetPayloadLength());
            m_current_size += rtppack.GetPayloadLength();
        }
    }

}


void StartReceive()
{
    /*CRTPReceiver sess;*/
    sess.InitBufferSize();
    std::string ipstr;
    int status;

    // Now, we'll create a RTP session, set the destination
    // and poll for incoming data.
    RTPUDPv4TransmissionParams transparams;
    RTPSessionParams sessparams;

    // IMPORTANT: The local timestamp unit MUST be set, otherwise
    //            RTCP Sender Report info will be calculated wrong
    // In this case, we'll be just use 9000 samples per second.
    sessparams.SetOwnTimestampUnit(1.0/9000.0);     

    transparams.SetPortbase(PORT_BASE);
    status = sess.Create(sessparams,&transparams);  
    checkerror(status);

    uint32_t dst_ip = inet_addr(DST_IP);
    dst_ip = ntohl(dst_ip);
    RTPIPv4Address addr(dst_ip,DST_PORT);
    status = sess.AddDestination(addr);

    checkerror(status);
}

int main(int argc, char* argv[])
{
    WSADATA dat;
    WSAStartup(MAKEWORD(2,2),&dat);
    StartReceive();
    RTPTime::Wait(RTPTime(3,0));
    return 0;
}
至此,使用jrtplib传输h264全部完成。

你可能感兴趣的:(视频压缩传输,h.264,视频,rtp)