📄 rtcp.c
字号:
return s->myInfo.ssrc;}/*=========================================================================**** == rtcpSetSSRC() == **** **** Changes the synchronization source value for an RTCP session. **** **** PARAMETERS: **** hRTCP The handle of the RTCP session. **** **** ssrc A synchronization srouce value for the RTCP session. **** **** RETURNS: **** If the enumeration process was stopped by the enumerator, the **** function returns RV_FALSE, otherwise RV_TRUE. **** ****=========================================================================*/RVAPIRvInt32 RVCALLCONV rtcpSetSSRC( IN HRTCPSESSION hRTCP, IN RvUint32 ssrc){ rtcpSession *s = (rtcpSession *)hRTCP; s->myInfo.ssrc = ssrc; s->myInfo.collision = 0; return RV_OK;} /* == ENDS: Accessory RTCP Functions == */ /* == Internal RTCP Functions == */RVAPIRvInt32 RVCALLCONV rtcpGetEnumFirst( IN HRTCPSESSION hRTCP, IN RvInt32 * ssrc){ return rtcpGetEnumNext(hRTCP, -1, ssrc);}RVAPIRvInt32 RVCALLCONV rtcpGetEnumNext( IN HRTCPSESSION hRTCP, IN RvInt32 prev, IN RvInt32 * ssrc){ rtcpSession *s = (rtcpSession *)hRTCP; rtcpInfo* info; RvInt32 index, doAgain = 1; if (prev < 0) index = 0; else index = prev+1; while ((doAgain == 1)&&(index < s->sessionMembers)) { info = &s->participantsArray[index]; if (!info->invalid) { doAgain = 0; *ssrc = info->ssrc; } else { index++; } } if (index < s->sessionMembers) return index; else return -1;}/* todo: check reference guide about this function */RVAPIRvInt32 RVCALLCONV rtcpCreateRTCPPacket( IN HRTCPSESSION hRTCP, IN OUT RvRtpBuffer* buf){ rtcpSession *s = (rtcpSession *)hRTCP; rtcpHeader head; RvUint32 allocated = 0; RvRtpBuffer bufC; rtcpType type = RTCP_SR; int index; if (buffValid(buf, SIZEOF_RTCPHEADER + SIZEOF_SR)) { RvUint64 myTime = s->myInfo.eSR.tNNTP; RvUint8 cc = 0; rtcpInfo *info; allocated = SIZEOF_RTCPHEADER; if (s->myInfo.active) { s->myInfo.active = RV_FALSE; bufC = buffCreate(&(s->myInfo.eSR), SIZEOF_SR); buffAddToBuffer(buf, &bufC, allocated); ConvertToNetwork(buf->buffer + allocated, 0, W32Len(bufC.length)); allocated += SIZEOF_SR; } else { type = RTCP_RR; } index = 0; while( index < s->sessionMembers) { info = &s->participantsArray[index]; if (info->active) { info->eToRR.bfLost = getLost (&(info->src)); info->eToRR.nJitter = getJitter (&(info->src)); info->eToRR.nExtMaxSeq = getSequence(&(info->src)); info->eToRR.tDLSR = (info->tLSRmyTime) ? (reduceNNTP(myTime)-info->tLSRmyTime) : 0; bufC = buffCreate(&(info->eToRR), SIZEOF_RR); if (buffAddToBuffer(buf, &bufC, allocated)) { cc++; if (cc == 32) break; ConvertToNetwork(buf->buffer + allocated, 0, W32Len(bufC.length)); allocated += SIZEOF_RR; } info->active = RV_FALSE; } index++; } head = makeHeader(s->myInfo.ssrc, cc, type, (RvUint16)allocated); bufC = buffCreate(&head, SIZEOF_RTCPHEADER); buffAddToBuffer(buf, &bufC, 0); /* add an CNAME SDES packet to the compound packet */ if (buffValid(buf, allocated + SIZEOF_RTCPHEADER + SIZEOF_SDES(s->myInfo.eCName))) { RvRtpBuffer sdes_buf; /* 'sdes_buf' is inside the compound buffer 'buf' */ sdes_buf = buffCreate(buf->buffer + allocated, (SIZEOF_RTCPHEADER + SIZEOF_SDES(s->myInfo.eCName))); head = makeHeader(s->myInfo.ssrc, 1, RTCP_SDES, (RvUint16)sdes_buf.length); memcpy(sdes_buf.buffer, (char *)&head, SIZEOF_RTCPHEADER); memcpy(sdes_buf.buffer + SIZEOF_RTCPHEADER, &(s->myInfo.eCName), (RvSize_t)SIZEOF_SDES(s->myInfo.eCName)); allocated += sdes_buf.length; } if (s->myInfo.collision == 1 && buffValid(buf, allocated + SIZEOF_RTCPHEADER)) { head = makeHeader(s->myInfo.ssrc, 1, RTCP_BYE, SIZEOF_RTCPHEADER); bufC = buffCreate(&head, SIZEOF_RTCPHEADER); buffAddToBuffer(buf, &bufC, allocated); s->myInfo.collision = 2; allocated += SIZEOF_RTCPHEADER; } } buf->length = allocated; return RV_OK;}/* todo: check reference guide about this function */RVAPIRvInt32 RVCALLCONV rtcpProcessCompoundRTCPPacket( IN HRTCPSESSION hRTCP, IN OUT RvRtpBuffer* buf, IN RvUint64 myTime){ rtcpSession *s = (rtcpSession *)hRTCP; rtcpHeader *head; RvUint8 *currPtr, *dataPtr, *compoundEnd; RvInt32 hdr_count, hdr_len; rtcpType hdr_type; RvBool hdr_paddingbit = RV_FALSE; RvUint32 Padding = 0; currPtr = buf->buffer; compoundEnd = buf->buffer + buf->length; while (currPtr < compoundEnd) { head = (rtcpHeader*)(currPtr); ConvertFromNetwork(currPtr, 0, 1); hdr_count = bitfieldGet(head->bits, HEADER_RC, HDR_LEN_RC); hdr_type = (rtcpType)bitfieldGet(head->bits, HEADER_PT, HDR_LEN_PT); hdr_paddingbit = bitfieldGet(head->bits, HEADER_P, 1); if (hdr_paddingbit) { Padding = *(compoundEnd-1); compoundEnd = buf->buffer + buf->length - Padding; } hdr_len = sizeof(RvUint32) * (bitfieldGet(head->bits, HEADER_len, HDR_LEN_len)) - Padding; if ((compoundEnd - currPtr) < hdr_len) { return ERR_RTCP_ILLEGALPACKET; } if ((hdr_type > RTCP_LAST_LEGAL && hdr_type < RTCP_SR) || (hdr_len>1400 && hdr_len<0)) { return ERR_RTCP_ILLEGALPACKET; } dataPtr = (RvUint8 *)head + sizeof(RvUint32); rtcpProcessRTCPPacket(s, dataPtr, hdr_len, hdr_type, hdr_count, myTime); currPtr += (hdr_len + sizeof(RvUint32)); } return RV_OK;}RVAPIRvInt32 RVCALLCONV rtcpProcessRTCPPacket( IN rtcpSession * s, IN RvUint8 * data, IN RvInt32 dataLen, IN rtcpType type, IN RvInt32 reportCount, IN RvUint64 myTime){ unsigned scanned = 0; rtcpInfo info, *fInfo=NULL; info.ssrc = 0; if (dataLen == 0) return RV_OK; switch (type) { case RTCP_SR: case RTCP_RR: { ConvertFromNetwork(data, 0, 1); info.ssrc = *(RvUint32 *)(data); scanned = sizeof(RvUint32); if (info.ssrc == s->myInfo.ssrc) { s->myInfo.collision = 1; return ERR_RTCP_SSRCCOLLISION; } fInfo = findSSrc(s,info.ssrc); if (!fInfo) /* New source */ { /* insert the new source */ RvLockGet(&s->lock, logMgr); fInfo = insertNewSSRC(s, *(RvUint32 *)data); RvLockRelease(&s->lock, logMgr); } break; } default: break; } /* process the information */ switch (type) { case RTCP_SR: { ConvertFromNetwork(data + scanned, 0, W32Len(SIZEOF_SR)); if (fInfo) { memcpy(&(fInfo->eSR.tNNTP), (data + scanned), 8); memcpy(&(fInfo->eSR.tRTP), (data + scanned + 8), 4); memcpy(&(fInfo->eSR.nPackets), (data + scanned + 12), 4); memcpy(&(fInfo->eSR.nBytes), (data + scanned + 16), 4); fInfo->eToRR.tLSR = reduceNNTP(fInfo->eSR.tNNTP); fInfo->tLSRmyTime = reduceNNTP(myTime); } scanned += SIZEOF_SR; } /* fall into RR */ case RTCP_RR: { if ((fInfo != NULL) && ((RvInt32)scanned < dataLen)) { int i; rtcpRR* rr = (rtcpRR*)(data + scanned); ConvertFromNetwork(data + scanned, 0, reportCount * W32Len(sizeof(rtcpRR))); for (i=0; i < reportCount; i++) { if (rr[i].ssrc == s->myInfo.ssrc) { fInfo->eFromRR = rr[i]; break; } } } break; } case RTCP_SDES: { int i; rtcpSDES *sdes; for (i = 0; (i < reportCount) && ((RvInt32)scanned < dataLen); i++) { ConvertFromNetwork(data + scanned, 0, 1); info.ssrc = *(RvUint32 *)(data + scanned); sdes = (rtcpSDES *)(data + scanned + sizeof(info.ssrc)); fInfo = findSSrc(s,info.ssrc); if (fInfo != NULL) { scanned += sizeof(RvUint32); do { switch(sdes->type) { case RTCP_SDES_CNAME: memcpy(&(fInfo->eCName), sdes, (RvSize_t)(sdes->length+2)); 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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -