📄 rtcp.c
字号:
return res;
}
/*=========================================================================**
** == rtcpGetSSRC() == **
** **
** Returns the synchronization source value for an RTCP session. **
** **
** PARAMETERS: **
** hRTCP The handle of the RTCP session. **
** **
** RETURNS: **
** The synchronization source value for the specified RTCP session. **
** **
**=========================================================================*/
RVAPI
RvInt32 RVCALLCONV rtcpGetSSRC(
IN HRTCPSESSION hRTCP)
{
rtcpSession *s = (rtcpSession *)hRTCP;
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. **
** **
**=========================================================================*/
RVAPI
RvInt32 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 == */
RVAPI
RvInt32 RVCALLCONV rtcpGetEnumFirst(
IN HRTCPSESSION hRTCP,
IN RvInt32 * ssrc)
{
return rtcpGetEnumNext(hRTCP, -1, ssrc);
}
RVAPI
RvInt32 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 */
RVAPI
RvInt32 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 */
RVAPI
RvInt32 RVCALLCONV rtcpProcessCompoundRTCPPacket(
IN HRTCPSESSION hRTCP,
IN OUT RvRtpBuffer* buf,
IN RvUint64 myTime)
{
rtcpSession *s = (rtcpSession *)hRTCP;
rtcpHeader *head;
RvUint8 *currPtr = buf->buffer, *dataPtr, *compoundEnd;
int hdr_count, hdr_len;
rtcpType hdr_type;
compoundEnd = buf->buffer + buf->length;
while (currPtr < compoundEnd)
{
if ((compoundEnd + 1 - currPtr) < 1)
{
return ERR_RTCP_ILLEGALPACKET;
}
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_len = sizeof(RvUint32) *
(bitfieldGet(head->bits, HEADER_len, HDR_LEN_len));
if ((compoundEnd - currPtr) < hdr_len)
{
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;
}
RVAPI
RvInt32 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;
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);
fInfo = insertNewSSRC(s, *(RvUint32 *)data);
RvLockRelease(&s->lock);
}
break;
}
default:
break;
}
/* process the information */
switch(type)
{
case RTCP_SR:
{
ConvertFromNetwork(data + scanned, 0, W32Len(sizeof(rtcpSR)));
if (fInfo)
{
fInfo->eSR = *(rtcpSR *)(data + scanned);
fInfo->eToRR.tLSR = reduceNNTP(fInfo->eSR.tNNTP);
fInfo->tLSRmyTime = reduceNNTP(myTime);
}
scanned += SIZEOF_SR;
}
/* fall into RR */
case RTCP_RR:
{
if (fInfo)
{
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; i++)
{
ConvertFromNetwork(data + scanned, 0, 1);
info.ssrc = *(RvUint32 *)(data + scanned);
sdes = (rtcpSDES *)(data + scanned + sizeof(info.ssrc));
fInfo = findSSrc(s,info.ssrc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -