📄 rtcp.c
字号:
if (fInfo)
{
switch(sdes->type)
{
case RTCP_SDES_CNAME:
memcpy(&(fInfo->eCName), sdes, (RvSize_t)SIZEOF_SDES(*sdes));
fInfo->eCName.value[sdes->length] = 0;
break;
/* known SDES types that are not handled:
case RTCP_SDES_END:
case RTCP_SDES_NAME:
case RTCP_SDES_EMAIL:
case RTCP_SDES_PHONE:
case RTCP_SDES_LOC:
case RTCP_SDES_TOOL:
case RTCP_SDES_NOTE:
case RTCP_SDES_PRIV:
break;
*/
}
}
scanned += SIZEOF_SDES(*sdes) + sizeof(RvUint32);
}
break;
}
case RTCP_BYE:
{
int i;
for (i = 0; i < reportCount; i++)
{
ConvertFromNetwork(data + scanned, 0, 1);
info.ssrc = *(RvUint32 *)(data + scanned);
scanned += sizeof(info.ssrc);
fInfo = findSSrc(s,info.ssrc);
if (fInfo)
{
/* We don't really delete this SSRC, we just mark it as invalid */
fInfo->invalid = RV_TRUE;
fInfo->ssrc = 0;
}
}
break;
}
case RTCP_APP:
break;
}
return RV_OK;
}
static RvBool rtcpTimerCallback(IN void* key)
{
rtcpSession* s = (rtcpSession*)key;
RvUint32 data[MAXRTCPPACKET/sizeof(RvUint32)+1];
RvRtpBuffer buf;
buf = buffCreate(data, MAXRTCPPACKET);
rtcpCreateRTCPPacket((HRTCPSESSION)s, &buf);
RvSocketSendBuffer(&s->socket, buf.buffer, (RvSize_t)buf.length, &s->remoteAddress, NULL);
return RV_TRUE; /* Make sure the timer is rescheduled */
}
static void rtcpEventCallback(
IN RvSelectEngine* selectEngine,
IN RvSelectFd* fd,
IN RvSelectEvents selectEvent,
IN RvBool error)
{
rtcpSession* s;
RvUint32 buffer[MAXRTCPPACKET/sizeof(RvUint32)+1];
RvRtpBuffer buf;
RvStatus res;
RvAddress remoteAddress, localAddress;
RvSize_t bytesReceived;
RV_UNUSED_ARG(selectEngine);
RV_UNUSED_ARG(selectEvent);
RV_UNUSED_ARG(error);
s = RV_GET_STRUCT(rtcpSession, selectFd, fd);
buf = buffCreate(buffer, MAXRTCPPACKET);
res = RvSocketReceiveBuffer(&s->socket, buf.buffer, (RvSize_t)buf.length, &bytesReceived, &remoteAddress);
if (res == RV_OK)
{
buf.length = (RvUint32)bytesReceived;
RvSocketGetLocalAddress(&s->socket, &localAddress);
if ((RvAddressGetIpPort(&remoteAddress) != RvAddressGetIpPort(&localAddress)) ||
!isMyIP(RvAddressIpv4GetIp(RvAddressGetIpv4(&remoteAddress))))
{
RvInt32 res=rtcpProcessCompoundRTCPPacket((HRTCPSESSION)s, &buf, getNNTPTime());
if ((res==0) && (s->rtcpRecvCallback != NULL))
{
RvUint32 ssrc=getSSRCfrom(buf.buffer);
s->rtcpRecvCallback((HRTCPSESSION)s, s->haRtcp, ssrc);
}
}
}
}
static RvUint64 getNNTPTime(void)
{
RvTime t;
RvNtpTime ntptime;
RvUint64 result;
RvTimeConstruct(&t, 0, 0); /* create and clear time structure */
RvClockGet(&t); /* Get current wall-clock time */
RvNtpTimeConstructFromTime(&ntptime, &t, RV_NTPTIME_ABSOLUTE); /* convert to NTP time */
result = RvNtpTimeTo64(&ntptime, 32, 32); /* Convert to format getNNTPTime returns */
RvNtpTimeDestruct(&ntptime); /* clean up */
RvTimeDestruct(&t); /* clean up */
return result;
}
static RvBool isMyIP(RvUint32 ip)
{
int i;
for (i=0; rvRtcpInstance.hostIPs[i]; i++)
{
if (ip == rvRtcpInstance.hostIPs[i])
{
return RV_TRUE;
}
}
return RV_FALSE;
}
static void setSDES(rtcpSDesType type, rtcpSDES* sdes, RvUint8 *data, int length)
{
sdes->type = (unsigned char)type;
sdes->length = (unsigned char)length;
memcpy(sdes->value, data, (RvSize_t)length);
memset(sdes->value+length, 0, (RvSize_t)( 4-((length+2)%sizeof(RvUint32)) ));
}
static void init_seq(rtpSource *s, RvUint16 seq)
{
s->base_seq = seq;
s->max_seq = seq;
s->bad_seq = RTP_SEQ_MOD + 1;
s->cycles = 0;
s->received = 0;
s->received_prior = 0;
s->expected_prior = 0;
}
static int update_seq(rtpSource *s, RvUint16 seq, RvUint32 ts, RvUint32 arrival)
{
RvUint16 udelta = (RvUint16)(seq - s->max_seq);
if (s->probation)
{
if (seq == s->max_seq + 1)
{
s->probation--;
s->max_seq = seq;
if (s->probation == 0)
{
init_seq(s, seq);
s->received++;
return 1;
}
}
else
{
s->probation = MIN_SEQUENTIAL - 1;
s->max_seq = seq;
}
return RV_OK;
}
else if (udelta < MAX_DROPOUT)
{
if (seq < s->max_seq) s->cycles += RTP_SEQ_MOD;
s->max_seq = seq;
}
else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER)
{
if (seq == s->bad_seq)
{
init_seq(s, seq);
}
else
{
s->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1);
return RV_OK;
}
}
else
{
/* duplicate or reordered packet */
}
{
RvInt32 transit = (RvInt32)(arrival - ts);
RvInt32 d = (RvInt32)(transit - s->transit);
s->transit = transit;
if (d < 0) d = -d;
s->jitter += d - ((s->jitter + 8) >> 4);
}
s->received++;
return 1;
}
/*=========================================================================**
** == makeHeader() == **
** **
** Creates an RTCP packet header. **
** **
** PARAMETERS: **
** ssrc A synchronization source value for the RTCP session. **
** **
** count A count of sender and receiver reports in the packet. **
** **
** type The RTCP packet type. **
** **
** dataLen The length of the data in the packet buffer, in **
** octets, including the size of the header. **
** **
** RETURNS: **
** The function returns a header with the appropriate parameters. **
** **
**=========================================================================*/
static rtcpHeader makeHeader(RvUint32 ssrc, RvUint8 count, rtcpType type,
RvUint16 dataLen)
{
rtcpHeader header;
header.ssrc = ssrc;
header.bits = RTCP_HEADER_INIT;
header.bits = bitfieldSet(header.bits, count, HEADER_RC, HDR_LEN_RC);
header.bits = bitfieldSet(header.bits, type, HEADER_PT, HDR_LEN_PT);
header.bits = bitfieldSet(header.bits, W32Len(dataLen) - 1, HEADER_len, HDR_LEN_len);
ConvertToNetwork(&header, 0, W32Len(SIZEOF_RTCPHEADER));
return header;
}
static RvUint32 getLost(rtpSource *s)
{
RvUint32 extended_max;
RvUint32 expected;
RvInt32 received_interval;
RvInt32 expected_interval;
RvInt32 lost;
RvInt32 lost_interval;
RvUint8 fraction;
extended_max = s->cycles + s->max_seq;
expected = extended_max - s->base_seq + 1;
lost = expected - s->received;
expected_interval = expected - s->expected_prior;
s->expected_prior = expected;
received_interval = s->received - s->received_prior;
s->received_prior = s->received;
lost_interval = expected_interval - received_interval;
if (expected_interval == 0 || lost_interval <= 0)
fraction = 0;
else
fraction = (RvUint8)((lost_interval << 8) / expected_interval);
return (fraction << 24) + lost;
}
static RvUint32 getJitter(rtpSource *s)
{
return s->jitter >> 4;
}
static RvUint32 getSequence(rtpSource *s)
{
return s->max_seq + s->cycles;
}
static RvUint32 getSSRCfrom(RvUint8 *head)
{
RvUint8 *ssrcPtr = (RvUint8 *)head + sizeof(RvUint32);
return *(RvUint32 *)(ssrcPtr);
}
static rtcpInfo *findSSrc(rtcpSession *s, RvUint32 ssrc)
{
int index = 0;
RvBool doAgain = RV_TRUE;
rtcpInfo *pInfo;
if (s == NULL)
return NULL;
/* Look for the given SSRC */
while ((doAgain) && (index < s->sessionMembers))
{
if (s->participantsArray[index].ssrc == ssrc)
doAgain = RV_FALSE;
else
index ++;
}
if (index < s->sessionMembers )
pInfo = &s->participantsArray[index];
else
pInfo = NULL;
return pInfo;
}
static rtcpInfo *insertNewSSRC(rtcpSession *s, RvUint32 ssrc)
{
rtcpInfo* pInfo = NULL;
int index;
if (s->sessionMembers >= s->maxSessionMembers)
{
/* We've got too many - see if we can remove some old ones */
index = 0;
while ((index < s->sessionMembers) &&
(s->participantsArray[index].invalid && s->participantsArray[index].ssrc == 0))
index++;
}
else
{
/* Add it as a new one to the list */
index = s->sessionMembers;
s->sessionMembers++;
}
if (index < s->sessionMembers)
{
/* Got a place for it ! */
pInfo = &s->participantsArray[index];
memset(pInfo, 0, sizeof(rtcpInfo));
pInfo->ssrc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -