博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用jrtplib(RTP)传输H.264视频文件(2)
阅读量:6982 次
发布时间:2019-06-27

本文共 4626 字,大约阅读时间需要 15 分钟。

hot3.png

上一篇我们介绍了RTP协议的一些基本知识,下面我们介绍如何使用jrtplib这个库传输H264编码。

JRTP传输:好了,下面是我写的使用JRTP进行发送H264数据包的例子,具体解释可以看注释。发送端也可以接收接收端发送过来的RTCP数据包。#define MAX_RTP_PKT_LENGTH 1360#define H264               96bool CheckError(int rtperr);class CRTPSender :	public RTPSession{public:	CRTPSender(void);	~CRTPSender(void);protected:	void OnAPPPacket(RTCPAPPPacket *apppacket,const RTPTime &receivetime,const RTPAddress *senderaddress);	void OnBYEPacket(RTPSourceData *srcdat);	void OnBYETimeout(RTPSourceData *srcdat);public:	void SendH264Nalu(unsigned char* m_h264Buf,int buflen);	void SetParamsForSendingH264();};bool CheckError(int rtperr){	if (rtperr < 0)	{		std::cout<<"ERROR: "<
<
GetSubType()<
GetAPPData()<
SendPacket((void *)sendbuf,buflen);    CheckError(status); }   else if(buflen > MAX_RTP_PKT_LENGTH) { //设置标志位Mark为0 this->SetDefaultMark(false); //printf("buflen = %d\n",buflen); //得到该需要用多少长度为MAX_RTP_PKT_LENGTH字节的RTP包来发送 int k=0,l=0;   k = buflen / MAX_RTP_PKT_LENGTH; l = buflen % MAX_RTP_PKT_LENGTH; int t=0;//用指示当前发送的是第几个分片RTP包 char nalHeader = pSendbuf[0]; // NALU 头ª¡¤ while( t < k || ( t==k && l>0 ) )   {   if( (0 == t ) || ( t
SendPacket((void *)sendbuf,MAX_RTP_PKT_LENGTH+2);*/ memcpy(sendbuf,&pSendbuf[t*MAX_RTP_PKT_LENGTH],MAX_RTP_PKT_LENGTH); status = this->SendPacket((void *)sendbuf,MAX_RTP_PKT_LENGTH); CheckError(status); t++; } //最后一包 else if( ( k==t && l>0 ) || ( t== (k-1) && l==0 )) { //设置标志位Mark为1 this->SetDefaultMark(true); int iSendLen; if ( l > 0) { iSendLen = buflen - t*MAX_RTP_PKT_LENGTH; } else iSendLen = MAX_RTP_PKT_LENGTH; //sendbuf[0] = (nalHeader & 0x60)|28;   //sendbuf[1] = (nalHeader & 0x1f); //sendbuf[1] |= 0x40; //memcpy(sendbuf+2,&pSendbuf[t*MAX_RTP_PKT_LENGTH],iSendLen); //status = this->SendPacket((void *)sendbuf,iSendLen+2);    memcpy(sendbuf,&pSendbuf[t*MAX_RTP_PKT_LENGTH],iSendLen); status = this->SendPacket((void *)sendbuf,iSendLen); CheckError(status); t++; } } }}void CRTPSender::SetParamsForSendingH264(){ this->SetDefaultPayloadType(H264);//设置传输类型 this->SetDefaultMark(true); //设置位 this->SetTimestampUnit(1.0/9000.0); //设置采样间隔 this->SetDefaultTimestampIncrement(3600);//设置时间戳增加间隔}void CRTPSender::OnBYEPacket(RTPSourceData *srcdat){}void CRTPSender::OnBYETimeout(RTPSourceData *srcdat){}Main.cpp  在上一篇博客中的编码之后进行传输#define SSRC           100#define DEST_IP_STR   "192.168.1.252"#define DEST_PORT     1234#define BASE_PORT     2222int iNal   = 0;x264_nal_t* pNals = NULL;void SetRTPParams(CRTPSender& sess,uint32_t destip,uint16_t destport,uint16_t baseport){ int status;   //RTP+RTCP库初始化SOCKET环境 RTPUDPv4TransmissionParams transparams; RTPSessionParams sessparams; sessparams.SetOwnTimestampUnit(1.0/9000.0); //时间戳单位 sessparams.SetAcceptOwnPackets(true); //接收自己发送的数据包 sessparams.SetUsePredefinedSSRC(true);  //设置使用预先定义的SSRC sessparams.SetPredefinedSSRC(SSRC);     //定义SSRC    transparams.SetPortbase(baseport); status = sess.Create(sessparams,&transparams);   CheckError(status); destip = ntohl(destip); RTPIPv4Address addr(destip,destport); status = sess.AddDestination(addr); CheckError(status); //为发送H264包设置参数 //sess.SetParamsForSendingH264();}bool InitSocket(){ int Error; WORD VersionRequested; WSADATA WsaData; VersionRequested=MAKEWORD(2,2); Error=WSAStartup(VersionRequested,&WsaData); //启动WinSock2 if(Error!=0) { printf("Error:Start WinSock failed!\n"); return false; } else { if(LOBYTE(WsaData.wVersion)!=2||HIBYTE(WsaData.wHighVersion)!=2) { printf("Error:The version is WinSock2!\n"); WSACleanup(); return false; } } return true;}void CloseSocket(CRTPSender sess){ //发送一个BYE包离开会话最多等待秒钟超时则不发送 sess.BYEDestroy(RTPTime(3,0),0,0); WSACleanup();}int main(int argc, char** argv){ InitSocket(); CRTPSender sender; string destip_str = "127.0.0.1"; uint32_t dest_ip = inet_addr(destip_str.c_str()); SetRTPParams(sender,dest_ip,DEST_PORT,BASE_PORT); sender.SetParamsForSendingH264(); //…x264设置参数等步骤,具体参见上篇博客 for(int i = 0; i < nFrames ; i++ ) { //读取一帧 read_frame_y4m(pPicIn,(hnd_t*)y4m_hnd,i); if( i ==0 ) pPicIn->i_pts = i; else pPicIn->i_pts = i - 1; //编码 int frame_size = x264_encoder_encode(pX264Handle,&pNals,&iNal,pPicIn,pPicOut); if(frame_size >0) { for (int i = 0; i < iNal; ++i) {//将编码数据写入文件t //fwrite(pNals[i].p_payload, 1, pNals[i].i_payload, pFile); //发送编码文件 sender.SendH264Nalu(pNals[i].p_payload,pNals[i].i_payload); RTPTime::Wait(RTPTime(1,0)); } } }  CloseSocket(sender); //一些清理工作…}

转载于:https://my.oschina.net/u/2348884/blog/408385

你可能感兴趣的文章
数的全排列
查看>>
2015年最新手机号码正则表达式
查看>>
public private protected 区别
查看>>
IntelliJ IDEA常用设置及快捷键
查看>>
KVM: 安装Windows virtio半虚拟化驱动
查看>>
hdu2669 扩展欧几里得
查看>>
PHP 基础
查看>>
Delphi判断字符串是否是数字、字母、大小写字母
查看>>
POJ NOI0105-45 金币
查看>>
Project Euler Problem 15 Lattice paths
查看>>
组合模式
查看>>
Python之路番外(第三篇):Pycharm的使用秘籍
查看>>
alpha冲刺9
查看>>
Hibernate组件映射
查看>>
转:目标检测算法总结
查看>>
springmvc @valid
查看>>
抓包工具 - Fiddler - (三)
查看>>
使用Hibernate注解 @Transient
查看>>
【POJ3294】 Life Forms(SA)
查看>>
让思路更清晰——我是怎样使用思维导图的
查看>>