2,542
社区成员
发帖
与我相关
我的任务
分享
#include "StdAfx.h"
#include "RTPClass.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
//////
CRTPClass::CRTPClass(void)
{
bInitRTP = false;
}
//////////////////////////////////////////////////////////////////////////
void CRTPClass::SetRTPParam(CString ip,int port)
{
rtp_ip = ip;
rtp_port = port;
}
bool CRTPClass::InitRTP()
{
//rtp_ip = ip;
//rtp_port = port;
if ( InitSocket())
{
//RTP+RTCP库初始化SOCKET环境
RTPUDPv4TransmissionParams transparams;
RTPSessionParams sessparams;
sessparams.SetOwnTimestampUnit(1.0/90000.0); //时间戳单位
sessparams.SetAcceptOwnPackets(true);
uint16_t portbase = rtp_port*10; //PORT_LOCAL;
transparams.SetPortbase(portbase);
int status;
status = sess.Create(sessparams,&transparams);
if (!checkerror(status))
{
return false;
}
uint32_t destip;
destip = inet_addr(rtp_ip);
destip = ntohl(destip);
uint16_t destport = rtp_port;
RTPIPv4Address addr(destip,rtp_port);
status = sess.AddDestination(addr);
if (!checkerror(status))
{
return false;
}
sess.SetDefaultPayloadType(96);
sess.SetDefaultMark(false);
sess.SetDefaultTimestampIncrement(3600);
bInitRTP = true;
return true;
}
return false;
}
bool CRTPClass::InitSocket()
{
int Error;
WORD VersionRequested;
WSADATA WsaData;
VersionRequested=MAKEWORD(2,2);
Error=WSAStartup(VersionRequested,&WsaData); //启动WinSock2
if(Error!=0)
{
return false;
}
else
{
if(LOBYTE(WsaData.wVersion)!=2||HIBYTE(WsaData.wHighVersion)!=2)
{
WSACleanup();
return false;
}
}
return true;
}
void CRTPClass::SendRTPH264(unsigned char* m_h264Buf,int buflen)
{
if (!bInitRTP)
{
if (!InitRTP())
{
TRACE("InitRTP fail\n");
return;
}
}
unsigned char *pbuf = new unsigned char[buflen];
memcpy(pbuf,m_h264Buf,buflen);
char sendbuf[1400];
memset(sendbuf,0,1400);
int status;
if (buflen<=MAX_RTP_PKT_LENGTH)
{
memcpy(sendbuf,pbuf,buflen);
status = sess.SendPacket((void *)sendbuf,buflen/*,payload,false,timestamp*/);
checkerror(status);
}
else if(buflen>=MAX_RTP_PKT_LENGTH)
{
//TRACE("buflen = %d\n",buflen);
//得到该nalu需要用多少长度为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 =pbuf[0]; // NALU 头
while(t<k||(t==k&&l>0))
{
if((0==t)||(t<k&&0!=t))//第一包到最后一包的前一包
{
sendbuf[0] = (nalHeader & 0x60)|28;
sendbuf[1] = (nalHeader & 0x1f);
if (0==t)
{
sendbuf[1] |= 0x80;
}
memcpy(sendbuf+2,&pbuf[t*MAX_RTP_PKT_LENGTH],MAX_RTP_PKT_LENGTH+2);
status = sess.SendPacket((void *)sendbuf,MAX_RTP_PKT_LENGTH+2/*,payload,false,timestamp*/);
checkerror(status);
t++;
}
//最后一包
else if((k==t&&l>0)||(t==(k-1)&&l==0)
{
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,&pbuf[t*MAX_RTP_PKT_LENGTH],iSendLen+2);
//TRACE("start = %d,len = %d\n",t*MAX_RTP_PKT_LENGTH,iSendLen);
status = sess.SendPacket((void *)sendbuf,iSendLen+2/*,payload,false,timestamp*/);
checkerror(status);
t++;
// Sleep(100);
}
}
#ifndef RTP_SUPPORT_THREAD
status = sess.Poll();
checkerror(status);
#endif
RTPTime::Wait(RTPTime(0,500)); //第一个参数为秒,第二个参数为毫秒
}
delete []pbuf;
}
void CRTPClass::CloseSocket()
{
if (bInitRTP)
{
//发送一个BYE包离开会话,最多等待3秒钟,超时则不发送
sess.BYEDestroy(RTPTime(3,0),0,0);
#ifdef WIN32
WSACleanup();
#endif // WIN32
}
}
bool CRTPClass::checkerror(int rtperr)
{
if (rtperr < 0)
{
TRACE("ERROR:%s\n",RTPGetErrorString(rtperr));
return false;
}
return true;
}