📄 rtcp.c
字号:
case RTCP_SDES_PRIV: break;*/ } scanned += (sdes->length+2); sdes = (rtcpSDES *)(data + scanned); } while (*(RvUint8 *)(data + scanned) != 0 && ((RvInt32)scanned < dataLen)); } } break; } case RTCP_BYE: { RvInt32 i; ConvertFromNetwork(data, 0, 1); info.ssrc = *(RvUint32 *)(data); scanned = sizeof(RvUint32); 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 != NULL) { /* 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, logMgr, 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, logMgr, &bytesReceived, &remoteAddress); if (res == RV_OK) { buf.length = (RvUint32)bytesReceived; RvSocketGetLocalAddress(&s->socket, logMgr, &localAddress); if ((RvAddressGetIpPort(&remoteAddress) != RvAddressGetIpPort(&localAddress)) || !isMyIP(RvAddressIpv4GetIp(RvAddressGetIpv4(&remoteAddress)))) { /*lint -e578*/ 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(0, 0, &t); /* create and clear time structure */ RvClockGet(NULL, &t); /* Get current wall-clock time */ RvNtpTimeConstructFromTime(&t, RV_NTPTIME_ABSOLUTE, &ntptime); /* 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 = ssrc; pInfo->eToRR.ssrc = ssrc; pInfo->active = RV_FALSE; pInfo->src.probation = MIN_SEQUENTIAL - 1; } return pInfo;} /* == ENDS: Internal RTCP Functions == */#ifdef __cplusplus}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -