使用Jrtplib实现RTP视频数据发送接收

Posted 西北老码农

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Jrtplib实现RTP视频数据发送接收相关的知识,希望对你有一定的参考价值。

        在网上下载获取Jrtplib包的源码,解压缩配置编译安装以后就可以使用,下载的代码包里面有example代码示例:

        示例都是基于Jrtplib的RTP/RTCP协议栈实现,在设置Server端的时候,与TCP/IP协议不一样,首先在初始化打开的Session的时候,设置一个baseport端口,同时设置Client端的ip和port,然后再根据视频采样的频率设置时间戳,具体的设置函数都可以在examples中找到并且能很好的复用。

示例代码的RTP/RTCP发送和接收都是通过线程来实现的:

1、发送线程代码实现:

ret = Send_rtppacket((unsigned char*)videoIn.ptframe[frameout],sizeof(struct frame_t)+headerframe->size);
在发送线程函数中直接发送ptframe[]指针指向的数据,数据大小为sizeof(struct frame_t)+headerframe->size,包含了该frame的数据,以及对该frame参数描述的数据结构。
int Send_rtppacket(unsigned char* framepointer,int framelength)

	int done = 0;
	int flage;
	int sendbyte = 0;
	int n;
	do
		if(framelength > PacketMaxsize)   //设置packetmaxsize: 1400 , oversize情况下就要分割传输
			flage = 0;
		else flage =1;
		if(flage = 1) 
			n = session.SendPacket(framepointer,framelength,26,1,1000);   //发送函数 第四个参数决定是否是该frame最后小于1400的数据
			done = 1;                                                     //如果是 标示完成
			sendbyte = framelength;
		else
			n = session.SendPacket(framepointer,PacketMaxsize,26,0,1000);
			framepointer = framepointer + PacketMaxsize ;                               //update发送指针
			framelength = framelength - PacketMaxsize ;
			sendbyte = sendbyte + PacketMaxsize;
		
		if(n<0) 
			return -1;
		
		RTPTime::Wait (delay);
	while(!done);
	return  sendbyte;

2、接收线程代码实现

do 
	// 检索RTP数据源
	sess.BeginDataAccess();
	if (sess.GotoFirstSourceWithData()) 
        do 
			RTPPacket* packet;
			RTPSourceData *srcdata;
			// 获取RTP数据报
			packetflage =0;
			recvlength =0;     //初始化接收数据 以及数据接收标示
			while ((packet = sess.GetNextPacket()) != NULL && packetflage==0)   //标示为零 接收同一packet的剩余数据
				//printf("Got packet !/n");
				
				if(processpacket(*srcdata,*packet))
					packetflage = 1; //processpacket() 返回1 已经接受到所有的packet 可以调用解码,SDL显示
					//printf("Debug...packetflage: %d/n",packetflage);
					jpegsize = readjpeg(&buf,headerframe);
					//printf("Debug...jpegsize: %d/n",jpegsize);
					if(!jpegsize && videoOk)
						close_sdlvideo(); 
					if(jpegsize && !videoOk)
						init_sdlvideo();  
						pscreen = SDL_SetVideoMode (owidth, oheight, bpp * 8,SDL_DOUBLEBUF | SDL_SWSURFACE);
						p=(unsigned char*)pscreen->pixels;
					
					if(jpegsize && videoOk) 
						jpeg_decode(&picture,buf,&width,&height);
						resize (p,picture,owidth,oheight,width,height) ;
						SDL_WM_SetCaption (titre, NULL);
						SDL_Flip (pscreen); 
					
					if(SDL_PollEvent (&sdlevent)<0) goto error;
				   
				else packetflage =0;   //返回0,packet还没接受完 继续sess.GetNextPacket()
				delete packet;  // 删除RTP数据报
			
		 while (sess.GotoNextSourceWithData));   //接收另一个packet
    
	sess.EndDataAccess();
	// 接受RTP数据
	status = sess.Poll();
	checkerror(status);
	RTPTime::Wait(RTPTime(1,0));
 while(1);
 
 
int processpacket(const RTPSourceData &srcdat,const RTPPacket &rtppack)

     unsigned char* payloadpointer = rtppack.GetPayloadData();    //接收该数据包数据
     bool packetmarker = rtppack.HasMarker();   //察看部否是已经传完该数据包
     int flage =1;
        //printf("Debug..........1/n");
     if(!packetmarker)   
		 memcpy(recvpointer+recvoffset,payloadpointer,rtppack.GetPayloadLength());
		 recvlength += rtppack.GetPayloadLength();
		 recvoffset += rtppack.GetPayloadLength();  //更新接收数据保存的指针
		 // printf("Debug..........2/n");
		 flage = 0;   //标示接受位 继续执行sess.GetNextPacket()
     
	 else
		 memcpy(recvpointer +recvoffset,payloadpointer,rtppack.GetPayloadLength());
		 recvlength += rtppack.GetPayloadLength();
		 recvoffset = 0;                     //传完,初始化
		 // printf("Debug..........3/n");
	 
	 return flage;

RTP/RTCP传输数据的流程:

Server端:

        发送定长的数据报到Client端,发送的时候是分批以packet的形式发送到Client,就是说发送一个数据包需要几次packet发送来完成。发送成功以后发送下一个数据包,始终调用函数:session.SendPacket();

Client端:

        依次循环调用sess.GetNextPacket()来接收某一数据包的packet数据,packet的到来不是按顺序到来的,完全接收到数据包所用的packets以后,RTP库在根据时间戳对接受的packet重新排序生成最终的数据包。接收数据包成功后,调用sess.GotoNextSourceWithData()开始接收下一个数据包。

 

以上是关于使用Jrtplib实现RTP视频数据发送接收的主要内容,如果未能解决你的问题,请参考以下文章

一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:RTP音视频传输解析层之音视频数据传输格式

一种RTP接收和解包的程序

RTP RTCP在音视频传输与同步方面的使用

一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:RTP音视频传输解析层之H264传输格式

测试库的接收到的数据是否完整(jrtplib为列)

一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:以g711-mulaw为例添加新的编码格式解析支持