使用jrtplib傳輸H.264視頻文件(3)

本文所有內容均爲原創,轉載請註明出處!

介紹如何發送h264,下面我們介紹下如何接收h264文件。

其中主要關注的就是被拆分的數據包的重組,下面的代碼中有詳盡的註釋。

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: "<<senderaddress<<std::endl;
}


void CRTPReceiver::OnPollThreadStep()
{
	BeginDataAccess();
		
	// check incoming packets
	if (GotoFirstSourceWithData())
	{
		do
		{
			RTPPacket *pack;
			RTPSourceData *srcdat;
			
			srcdat = GetCurrentSourceInfo();
			
			while ((pack = GetNextPacket()) != NULL)
			{
				ProcessRTPPacket(*srcdat,*pack);
				DeletePacket(pack);
			}
		} while (GotoNextSourceWithData());
	}
		
	EndDataAccess();
}

void CRTPReceiver::ProcessRTPPacket(const RTPSourceData &srcdat,const RTPPacket &rtppack)
{
	// You can inspect the packet and the source's info here
	//std::cout<<"Packet type: "<<rtppack.GetPayloadType()<<std::endl;
	//std::cout<<"Packet says: "<<(char *)rtppack.GetPayloadData()<<std::endl;
	//test RTCP packet
	/*int status = this->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() <<std::endl;
		if(rtppack.HasMarker())//如果是最後一包則進行組包
		{
			m_pVideoData->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全部完成。

發佈了28 篇原創文章 · 獲贊 19 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章