📄 rtcp.c
字号:
IN RvUint16 sequence)
{
RvListIter(rtcpInfo) iter;
rtcpHeader head;
rtcpSession *s = (rtcpSession *)hRTCP;
/*RvIpv4Addr ipv4;*/
RvSocketAddr toAddr;
rvMutexLock(&s->mutex);
if (ssrc == s->myInfo.ssrc)
{
s->myInfo.collision = 1;
rvMutexUnlock(&s->mutex);
return ERR_RTCP_SSRCCOLLISION;
}
for(iter = rvListBegin(&s->hList); iter != rvListEnd(&s->hList); iter = rvListIterNext(iter))
{
rtcpInfo *fInfo = rvListIterData(iter);
if(fInfo->ssrc == ssrc)
{
if (!fInfo->invalid)
{
fInfo->active = rvTrue;
update_seq(&(fInfo->src), sequence, localTimestamp, timestamp);
}
rvMutexUnlock(&s->mutex);
return 0;
}
}
/* create an invalid record */
head = makeHeader(ssrc, 0, RTCP_RR, SIZEOF_RTCPHEADER);
/* rvIpv4AddrConstruct(&ipv4, RV_INET_LOOPBACK); */
/* or ... */
/* rvIpv4AddrConstruct(&ipv4, inet_addr("127.0.0.1")); */
/*rvSocketAddrConstructIpv4(&toAddr, &ipv4, rvSocketGetPort(&s->socket));*/
rvSocketAddrConstructInet(&toAddr, &host, 0, rvSocketGetPort(&s->socket));
rvSocketSendTo(&s->socket, &head, SIZEOF_RTCPHEADER, &toAddr);
rvMutexUnlock(&s->mutex);
return 0;
}
/*=========================================================================**
** == 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. **
** **
**=========================================================================*/
RVVXDAPI
RvInt32 VXDCALLCONV rtcpRTPPacketSent(
IN HRTCPSESSION hRTCP,
IN RvInt32 bytes,
IN RvUint32 timestamp)
{
RvInt32 err;
rtcpSession *s = (rtcpSession *)hRTCP;
rvMutexLock(&s->mutex);
s->myInfo.active = rvTrue;
s->myInfo.eSR.nPackets++;
s->myInfo.eSR.nBytes += bytes;
s->myInfo.eSR.tNNTP = getNNTPTime();
s->myInfo.eSR.tRTP = timestamp;
err = s->myInfo.collision ? ERR_RTCP_SSRCCOLLISION : 0;
rvMutexUnlock(&s->mutex);
return err;
}
/*=========================================================================**
** == 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. **
** **
**=========================================================================*/
RVVXDAPI
RvUint16 VXDCALLCONV rtcpGetPort(
IN HRTCPSESSION hRTCP)
{
RvUint16 port;
rtcpSession *s = (rtcpSession *)hRTCP;
rvMutexLock(&s->mutex);
port = rvSocketGetPort(&s->socket);
rvMutexUnlock(&s->mutex);
return port;
}
/* == 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: **
** rvTrue is returned if a collision was detected, otherwise rvFalse. **
** **
**=========================================================================*/
RVVXDAPI
RvBool VXDCALLCONV 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 rvFalse, otherwise rvTrue. **
** **
** 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 rvFalse if it wants the enumeration process **
** to continue. Returning rvTrue will cause rtcpEnumParticipant() to **
** return immediately. **
** **
**=========================================================================*/
RVVXDAPI
RvBool VXDCALLCONV rtcpEnumParticipants(
IN HRTCPSESSION hRTCP,
IN LPSSRCENUM enumerator)
{
RvListIter(rtcpInfo) iter;
rtcpSession *s = (rtcpSession *)hRTCP;
rvMutexLock(&s->mutex);
for(iter = rvListBegin(&s->hList); iter != rvListEnd(&s->hList); iter = rvListIterNext(iter))
{
rtcpInfo *info = rvListIterData(iter);
if(info->invalid)
continue;
if(enumerator(hRTCP, info->ssrc))
{
rvMutexUnlock(&s->mutex);
return rvFalse;
}
}
rvMutexUnlock(&s->mutex);
return rvTrue;
}
/*=========================================================================**
** == rtcpGetSourceInfo() == **
** **
** Provides information about a particular synchronization source. **
** **
** TBD **
** **
**=========================================================================*/
RVVXDAPI
RvInt32 VXDCALLCONV rtcpGetSourceInfo(
IN HRTCPSESSION hRTCP,
IN RvUint32 ssrc,
OUT RTCPINFO * info)
{
RvListIter(rtcpInfo) iter;
rtcpSession *s = (rtcpSession *)hRTCP;
rvMutexLock(&s->mutex);
if (ssrc == s->myInfo.ssrc)
{
info->selfNode = rvTrue;
info->sr.valid = s->myInfo.active;
info->sr.mNTPtimestamp = s->myInfo.eSR.tNNTP.msdw;
info->sr.lNTPtimestamp = s->myInfo.eSR.tNNTP.lsdw;
info->sr.timestamp = s->myInfo.eSR.tRTP;
info->sr.packets = s->myInfo.eSR.nPackets;
info->sr.octets = s->myInfo.eSR.nBytes;
strncpy(info->cname, s->myInfo.eCName.value, sizeof(info->cname));
rvMutexUnlock(&s->mutex);
return 0;
}
for(iter = rvListBegin(&s->hList); iter != rvListEnd(&s->hList); iter = rvListIterNext(iter))
{
rtcpInfo *fInfo = rvListIterData(iter);
if(fInfo->ssrc == ssrc)
{
info->selfNode = rvFalse;
info->sr.valid = !fInfo->invalid;
info->sr.mNTPtimestamp = fInfo->eSR.tNNTP.msdw;
info->sr.lNTPtimestamp = fInfo->eSR.tNNTP.lsdw;
info->sr.timestamp = fInfo->eSR.tRTP;
info->sr.packets = fInfo->eSR.nPackets;
info->sr.octets = fInfo->eSR.nBytes;
info->rrFrom.valid = rvTrue;
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 = rvTrue;
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));
rvMutexUnlock(&s->mutex);
return 0;
}
}
rvMutexUnlock(&s->mutex);
return ERR_RTCP_ILLEGALSSRC;
}
/*=========================================================================**
** == 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 rvFalse, otherwise rvTrue. **
** **
**=========================================================================*/
RVVXDAPI
RvInt32 VXDCALLCONV rtcpSetGroupAddress(
IN HRTCPSESSION hRTCP,
IN RvUint32 ip)
{
rtcpSession *s = (rtcpSession *)hRTCP;
rvMutexLock(&s->mutex);
rvSocketJoinMulticastGroup(&s->socket, ip, RV_INET_ADDRANY);
rvMutexUnlock(&s->mutex);
return 0;
}
/*=========================================================================**
** == 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. **
** **
**=========================================================================*/
RVVXDAPI
RvInt32 VXDCALLCONV 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 rvFalse, otherwise rvTrue. **
** **
**=========================================================================*/
RVVXDAPI
RvInt32 VXDCALLCONV rtcpSetSSRC(
IN HRTCPSESSION hRTCP,
IN RvUint32 ssrc)
{
rtcpSession *s = (rtcpSession *)hRTCP;
rvMutexLock(&s->mutex);
s->myInfo.ssrc = ssrc;
s->myInfo.collision = 0;
rvMutexUnlock(&s->mutex);
return 0;
}
RvUint32 rtcpGetAvgTransmissionDelay(IN HRTCPSESSION hRTCP)
{
RvUint32 r;
rtcpSession *s = (rtcpSession *)hRTCP;
rvMutexLock(&s->mutex);
r = (s->numOfRRs) ? (s->rtt / s->numOfRRs) : 0;
rvMutexUnlock(&s->mutex);
return r/2;
}
/* == ENDS: Accessory RTCP Functions == */
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -