📄 rtcpreceiver.cpp
字号:
#include <libc\assert.h>
#include <libc\sys\time.h>
#include "vtypes.h"
#include <libc\string.h>
#include "cpLog.h"
#include "rtpTypes.h"
#include "rtpTools.h"
#include "NtpTime.h"
#include "RtpReceiver.h"
#include "RtcpReceiver.h"
#include "NtpTime.h"
/* ----------------------------------------------------------------- */
/* --- rtpcReceiver Constructor ------------------------------------ */
/* ----------------------------------------------------------------- */
RtcpReceiver::RtcpReceiver (CSocketUdp * udp,int localMinPort, int localMaxPort)
{
// myStack = new UdpStack(NULL, localMinPort, localMaxPort);
myStack = udp;
freeStack = true;
constructRtcpReceiver();
}
RtcpReceiver::RtcpReceiver (CSocketUdp * udp,int localPort)
{
// myStack = new UdpStack(NULL, localPort) ;
myStack = udp;
freeStack = true;
constructRtcpReceiver();
}
RtcpReceiver::RtcpReceiver (CSocketUdp* udp)
{
myStack = udp;
freeStack = false;
constructRtcpReceiver();
}
void RtcpReceiver::constructRtcpReceiver ()
{
packetReceived = 0;
accumOneWayDelay = 0;
avgOneWayDelay = 0;
accumRoundTripDelay = 0;
avgRoundTripDelay = 0;
}
RtcpReceiver::~RtcpReceiver ()
{
if (freeStack)
{
delete myStack;
myStack = 0;
}
// must remove each transmitter block and each SDES info
// map < RtpSrc, RtpTranInfo* > ::iterator s = tranInfoList.begin();
// while (s != tranInfoList.end())
// {
// removeTranInfo((s->second)->ssrc);
// s = tranInfoList.begin();
// }
for(TInt i=0; i<tranInfoList.Count(); i ++)
{
RtpTranInfo * pTranInfo = tranInfoList[i]->iTranInfo;
if(pTranInfo)
removeTranInfo(pTranInfo->ssrc);
}
tranInfoList.ResetAndDestroy();
tranInfoList.Close();
//cpLog(LOG_DEBUG_STACK, "RTCP: Receiver removed");
}
/* --- receive packet functions ------------------------------------ */
RtcpPacket* RtcpReceiver::getPacket ()
{
// 检查网络活动状态<-1>
/*ZHAOSONG
// check for network activity
fd_set netFD;
FD_ZERO (&netFD);
FD_SET (myStack->getSocketFD(), &netFD);
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int selret = select (myStack->getSocketFD() + 1,
&netFD, NULL, NULL, &timeout);
if (selret <= 0)
{
if (selret < 0) perror ("rtcpReceiver select");
else
return NULL;
}
else
{
//cpLog(LOG_DEBUG_STACK, "Get RTCP packet");
}
// create packet
*/
if( myStack->SelectRTCPStack() ==0)
return NULL;
RtcpPacket* p = new RtcpPacket ();
int len = myStack->RTCPreceive(p->getPacketData(),
p->getPacketAlloc());
// ? RtpTime arrival = generateTime ();
if (len <= 0)
{
delete p;
p = NULL;
return NULL;
}
p->setTotalUsage (len);
// kudo
// p->printPacket();
// check packet
if (!isValid(p))
{
delete p;
p = NULL;
return NULL;
}
return p;
}
int RtcpReceiver::isValid (RtcpPacket* p)
{
char* begin = reinterpret_cast < char* > (p->getPacketData());
char* end = reinterpret_cast < char* > (begin + p->getTotalUsage());
RtcpHeader* middle = reinterpret_cast < RtcpHeader* > (begin);
// check if known payload type for first packet
if (middle->type != rtcpTypeSR && middle->type != rtcpTypeRR)
return 0;
// check padbyte
if (middle->padding)
return 0;
// check header lengths
while (begin < end && (int)middle->version == RTP_VERSION)
{
begin += (ntohs(middle->length) + 1) * sizeof(RtpSrc);
middle = reinterpret_cast < RtcpHeader* > (begin);
}
if (begin != end)
return 0;
// exit with success
cpLog(LOG_DEBUG_STACK, "RTCP packet is valid");
// cout << "RTCP packet is valid" << endl;
return 1;
}
int RtcpReceiver::readRTCP (RtcpPacket* p)
{
char* begin = reinterpret_cast < char* > (p->getPacketData());
char* end = reinterpret_cast < char* > (begin + p->getTotalUsage());
RtcpHeader* middle = NULL;
int ret = 0;
while (begin < end)
{
middle = reinterpret_cast < RtcpHeader* > (begin);
switch (middle->type)
{
case (rtcpTypeSR):
case (rtcpTypeRR):
readSR (middle);
break;
case (rtcpTypeSDES):
readSDES (middle);
break;
case (rtcpTypeBYE):
if ( readBYE (middle) == 0)
{
ret = 1;
}
break;
case (rtcpTypeAPP):
readAPP (middle);
break;
default:
cpLog (LOG_ERR, "RTCP: Unknown RTCP type");
break;
}
begin += (ntohs(middle->length) + 1) * sizeof(u_int32_t);
}
return ret;
}
RtcpHeader* RtcpReceiver::findRTCP (RtcpPacket* p, RtcpType type)
{
char* begin = reinterpret_cast < char* > (p->getPacketData());
char* end = reinterpret_cast < char* > (begin + p->getTotalUsage());
RtcpHeader* middle = NULL;
while (begin < end)
{
middle = reinterpret_cast < RtcpHeader* > (begin);
if (type == static_cast < RtcpType > (middle->type))
return middle;
begin += (ntohs(middle->length) + 1) * sizeof(u_int32_t);
}
// packet type not found
cpLog (LOG_ERR, "RTCP: Type found here: %d", (int)type);
return NULL;
}
/* --- Read SR RTCP packet ----------------------------------------- */
int RtcpReceiver::readSR (RtcpPacket* p)
{
RtcpHeader* head = findRTCP (p, rtcpTypeSR);
if (head == NULL) head = findRTCP (p, rtcpTypeRR);
if (head == NULL) return -1;
readSR (head);
// read next RR packet if found
// future: - ?
return 0;
}
void RtcpReceiver::readSR (RtcpHeader* head)
{
char* middle = NULL;
NtpTime nowNtp = getNtpTime();
// read SR block
if (head->type == rtcpTypeSR)
{
RtcpSender* senderBlock = reinterpret_cast < RtcpSender* >
((char*)head + sizeof(RtcpHeader));
RtpTranInfo* s = findTranInfo(ntohl(senderBlock->ssrc));
s->lastSRTimestamp = (ntohl(senderBlock->ntpTimeSec) << 16 |
ntohl(senderBlock->ntpTimeFrac) >> 16);
s->recvLastSRTimestamp = nowNtp;
//printSR (senderBlock); // - debug
packetReceived++;
NtpTime thenNtp ( ntohl(senderBlock->ntpTimeSec),
ntohl(senderBlock->ntpTimeFrac) );
accumOneWayDelay += (nowNtp - thenNtp);
avgOneWayDelay = accumOneWayDelay / packetReceived;
middle = (char*)head + sizeof(RtcpHeader) + sizeof(RtcpSender);
}
else
{
// move over blank SR header
middle = (char*)head + sizeof(RtcpHeader);
// move over the ssrc of packet sender
RtpSrc* sender = reinterpret_cast < RtpSrc* > (middle);
RtpSrc ssrc;
ssrc = ntohl(*sender);
middle += sizeof(RtpSrc);
packetReceived++;
}
// read RR blocks
RtcpReport* block = reinterpret_cast < RtcpReport* > (middle);
for (int i = head->count; i > 0; i--)
{
//printRR (block); // - debug
// - ? what these are if the count is more than 1??
NtpTime thenNtp (ntohl(block->lastSRTimeStamp) >> 16,
ntohl(block->lastSRTimeStamp) << 16 );
NtpTime nowNtp1 (nowNtp.getSeconds() & 0x0000FFFF,
nowNtp.getFractional() & 0xFFFF0000);
accumRoundTripDelay += ((nowNtp1 - thenNtp)
- ntohl(block->lastSRDelay));
avgRoundTripDelay = accumRoundTripDelay / packetReceived;
++block;
}
// handle profile specific extensions
// - ?
}
void RtcpReceiver::printSR (RtcpSender* /*p*/)
{
// cerr << "Got SR from " << ntohl(p->ssrc) << endl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -