📄 rtcp.c
字号:
** **
** PARAMETERS: **
** hRTCP The handle of the RTCP session. **
** **
** localTimestamp The local timestamp for the received packet. **
** **
** timestamp The RTP timestamp from the received packet. **
** **
** sequence The packet sequence number. **
** **
** RETURNS: **
** A non-negative value upon success, or a negative integer error **
** code. **
** **
**=========================================================================*/
RVAPI
RvInt32 RVCALLCONV rtcpRTPPacketRecv(
IN HRTCPSESSION hRTCP,
IN RvUint32 ssrc,
IN RvUint32 localTimestamp,
IN RvUint32 myTimestamp,
IN RvUint16 sequence)
{
rtcpSession *s = (rtcpSession *)hRTCP;
rtcpInfo info, *fInfo;
if (ssrc == s->myInfo.ssrc)
{
s->myInfo.collision = 1;
return ERR_RTCP_SSRCCOLLISION;
}
info.ssrc = ssrc;
/* See if we can find this source or not */
fInfo = findSSrc(s,ssrc);
/* If we didn't find this SSRC, we lock the RTCP database and search for the
SSRC again. If we don't find it again - we insert it to the list, and
finally we unlock... */
if (!fInfo) /* New source */
{
/* this section is working with threads.*/
/* Lock the rtcp session.*/
RvLockGet(&s->lock);
/* check if the ssrc is exist*/
fInfo = findSSrc(s,ssrc);
if (!fInfo)
{
/* Still no SSRC - we should add it to the list ourselves */
fInfo = insertNewSSRC(s, ssrc);
}
/* unlock the rtcp session.*/
RvLockRelease(&s->lock);
}
if (fInfo != NULL)
{
if (!fInfo->invalid)
{
fInfo->active = RV_TRUE;
update_seq(&(fInfo->src), sequence, localTimestamp, myTimestamp);
}
}
return RV_OK;
}
/*=========================================================================**
** == rtcpRTPPacketSent() == **
** **
** Informs the RTCP session that a packet was sent in the corresponding **
** RTP session. **
** **
** PARAMETERS: **
** hRTCP The handle of the RTCP session. **
** **
** bytes The number of bytes in the sent packet. **
** **
** timestamp The RTP timestamp from the received packet. **
** **
** RETURNS: **
** A non-negative value upon success, or a negative integer error **
** code. **
** **
**=========================================================================*/
RVAPI
RvInt32 RVCALLCONV rtcpRTPPacketSent(
IN HRTCPSESSION hRTCP,
IN RvInt32 bytes,
IN RvUint32 timestamp)
{
rtcpSession *s = (rtcpSession *)hRTCP;
s->myInfo.active = RV_TRUE;
s->myInfo.eSR.nPackets++;
s->myInfo.eSR.nBytes += bytes;
s->myInfo.eSR.tNNTP = getNNTPTime();
s->myInfo.eSR.tRTP = timestamp;
if (s->myInfo.collision)
return ERR_RTCP_SSRCCOLLISION;
return RV_OK;
}
/*=========================================================================**
** == rtcpGetPort() == **
** **
** Gets the UDP port of an RTCP session. **
** **
** PARAMETERS: **
** hRTCP The handle of the RTCP session. **
** **
** RETURNS: **
** A non-negative value upon success, or a negative integer error **
** code. **
** **
**=========================================================================*/
RVAPI
RvUint16 RVCALLCONV rtcpGetPort(
IN HRTCPSESSION hRTCP)
{
rtcpSession* s = (rtcpSession *)hRTCP;
RvAddress localAddress;
RvUint16 sockPort = 0;
RvStatus res;
res = RvSocketGetLocalAddress(&s->socket, &localAddress);
if (res == RV_OK)
{
sockPort = RvAddressGetIpPort(&localAddress);
RvAddressDestruct(&localAddress);
}
return sockPort;
}
/* == ENDS: Basic RTCP Functions == */
/* == Accessory RTCP Functions == */
/*=========================================================================**
** == rtcpCheckSSRCCollision() == **
** **
** Checks for SSRC collisions in the RTCP session and the corresponding **
** RTP session. **
** **
** PARAMETERS: **
** hRTCP The handle of the RTCP session. **
** **
** RETURNS: **
** RV_TRUE is returned if a collision was detected, otherwise **
** RV_FALSE. **
** **
**=========================================================================*/
RVAPI
RvBool RVCALLCONV rtcpCheckSSRCCollision(
IN HRTCPSESSION hRTCP)
{
rtcpSession *s = (rtcpSession *)hRTCP;
return (s->myInfo.collision != 0);
}
/*=========================================================================**
** == rtcpEnumParticipants() == **
** **
** Provides information about in the RTCP session and the corresponding **
** RTP session. **
** **
** PARAMETERS: **
** hRTCP The handle of the RTCP session. **
** **
** enumerator A pointer to the function that will be called once per **
** SSRC in the session. **
** **
** RETURNS: **
** If the enumeration process was stopped by the enumerator, the **
** function returns RV_FALSE, otherwise RV_TRUE. **
** **
** The prototype of the SSRC enumerator is as follows: **
** **
** RvBool **
** SSRCENUM( **
** IN HRTPSESSION hTRCP, **
** IN RvUint32 ssrc **
** ); **
** **
** The parameters passed to the enumerator are as follows: **
** hRTCP The handle of the RTCP session. **
** **
** ssrc A synchronization source that participates in the **
** session. **
** **
** The enumerator should return RV_FALSE if it wants the enumeration **
** process to continue. Returning RV_TRUE will cause **
** rtcpEnumParticipant() to return immediately. **
** **
**=========================================================================*/
RVAPI
RvBool RVCALLCONV rtcpEnumParticipants(
IN HRTCPSESSION hRTCP,
IN LPSSRCENUM enumerator)
{
RvInt32 elem, ssrc=0;
elem = rtcpGetEnumFirst(hRTCP, &ssrc);
while (elem >= 0)
{
if (enumerator(hRTCP, ssrc))
{
return RV_FALSE;
}
elem = rtcpGetEnumNext(hRTCP, elem, &ssrc);
}
return RV_TRUE;
}
/*=========================================================================**
** == rtcpGetSourceInfo() == **
** **
** Provides information about a particular synchronization source. **
** **
** TBD **
** **
**=========================================================================*/
RVAPI
RvInt32 RVCALLCONV rtcpGetSourceInfo(
IN HRTCPSESSION hRTCP,
IN RvUint32 ssrc,
OUT RTCPINFO * info)
{
rtcpSession *s = (rtcpSession *)hRTCP;
rtcpInfo *fInfo, intInfo;
if (ssrc == s->myInfo.ssrc)
{
info->selfNode = RV_TRUE;
info->sr.valid = s->myInfo.active;
#if ((RV_OS_TYPE == RV_OS_TYPE_PSOS) && (RV_OS_VERSION == RV_OS_PSOS_2_0)) || \
(RV_OS_TYPE == RV_OS_TYPE_VXWORKS)
/* just to get rid of annoying warnings */
info->sr.mNTPtimestamp = (RvUint32)((s->myInfo.eSR.tNNTP >> 16) >> 16);
#else
info->sr.mNTPtimestamp = (RvUint32)(s->myInfo.eSR.tNNTP >> 32);
#endif
info->sr.lNTPtimestamp = (RvUint32)(s->myInfo.eSR.tNNTP & 0xffffffff);
info->sr.timestamp = s->myInfo.eSR.tRTP;
info->sr.packets = s->myInfo.eSR.nPackets;
info->sr.octets = s->myInfo.eSR.nBytes;
/* It's our node - receiver reports are not valid */
info->rrFrom.valid = RV_FALSE;
info->rrTo.valid = RV_FALSE;
strncpy(info->cname, s->myInfo.eCName.value, sizeof(info->cname));
return RV_OK;
}
intInfo.ssrc = ssrc;
fInfo = findSSrc(s,ssrc);
if (fInfo)
{
info->selfNode = RV_FALSE;
info->sr.valid = !fInfo->invalid;
#if ((RV_OS_TYPE == RV_OS_TYPE_PSOS) && (RV_OS_VERSION == RV_OS_PSOS_2_0)) || \
(RV_OS_TYPE == RV_OS_TYPE_VXWORKS)
/* just to get rid of annoying warnings */
info->sr.mNTPtimestamp = (RvUint32)((fInfo->eSR.tNNTP >> 16) >> 16);
#else
info->sr.mNTPtimestamp = (RvUint32)(fInfo->eSR.tNNTP >> 32);
#endif
info->sr.lNTPtimestamp = (RvUint32)(fInfo->eSR.tNNTP & 0xffffffff);
info->sr.timestamp = fInfo->eSR.tRTP;
info->sr.packets = fInfo->eSR.nPackets;
info->sr.octets = fInfo->eSR.nBytes;
info->rrFrom.valid = RV_TRUE;
info->rrFrom.fractionLost = (fInfo->eFromRR.bfLost >> 24);
info->rrFrom.cumulativeLost = (fInfo->eFromRR.bfLost & 0xffffff);
info->rrFrom.sequenceNumber = fInfo->eFromRR.nExtMaxSeq;
info->rrFrom.jitter = fInfo->eFromRR.nJitter;
info->rrFrom.lSR = fInfo->eFromRR.tLSR;
info->rrFrom.dlSR = fInfo->eFromRR.tDLSR;
info->rrTo.valid = RV_TRUE;
info->rrTo.fractionLost = (fInfo->eToRR.bfLost >> 24);
info->rrTo.cumulativeLost = (fInfo->eToRR.bfLost & 0xffffff);
info->rrTo.sequenceNumber = fInfo->eToRR.nExtMaxSeq;
info->rrTo.jitter = fInfo->eToRR.nJitter;
info->rrTo.lSR = fInfo->eToRR.tLSR;
info->rrTo.dlSR = fInfo->eToRR.tDLSR;
strncpy(info->cname, fInfo->eCName.value, sizeof(info->cname));
}
return (!fInfo) ? ERR_RTCP_ILLEGALSSRC : 0;
}
/*=========================================================================**
** == rtcpSetGroupAddress() == **
** **
** Specifies a multicast IP for an RTCP session. **
** **
** PARAMETERS: **
** hRTCP The handle of the RTCP session. **
** **
** ip The multicast IP address for the RTCP session. **
** SSRC in the session. **
** **
** RETURNS: **
** If the enumeration process was stopped by the enumerator, the **
** function returns RV_FALSE, otherwise RV_TRUE. **
** **
**=========================================================================*/
RVAPI
RvInt32 RVCALLCONV rtcpSetGroupAddress(
IN HRTCPSESSION hRTCP,
IN RvUint32 ip)
{
rtcpSession *s = (rtcpSession *)hRTCP;
RvAddress addresses[2];
RvStatus res;
RvAddressConstructIpv4(&addresses[0], ip, RV_ADDRESS_IPV4_ANYPORT);
RvAddressConstructIpv4(&addresses[1], rvRtcpInstance.localIp, RV_ADDRESS_IPV4_ANYPORT);
/* This function adds the specified address (in network format) to the specified
Multicast interface for the specified socket.*/
res = RvSocketJoinMulticastGroup(&s->socket, addresses, addresses + 1);
RvAddressDestruct(&addresses[0]);
RvAddressDestruct(&addresses[1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -