📄 rtcp.c
字号:
** code. **
** **
**=========================================================================*/
RVAPI
RvInt32 RVCALLCONV rtcpEnd(void)
{
RvStatus res;
rvRtcpInstance.timesInitialized--;
RvRtpEndTimerQueue();
res = RvRtpEndSelectEngine();
RvCBaseEnd();
return res;
}
RVAPI
RvInt32 RVCALLCONV rtcpSetRTCPRecvEventHandler(
IN HRTCPSESSION hRTCP,
IN LPRTCPEVENTHANDLER rtcpCallback,
IN void * context)
{
rtcpSession *s = (rtcpSession *)hRTCP;
s->rtcpRecvCallback=rtcpCallback;
s->haRtcp=context; /*context is Event to inform Ring3 about RTCP arrival*/
return RV_OK;
}
/*=========================================================================**
** == rtcpGetAllocationSize() **
** **
** Calculates an allocation size for RTCP session **
** **
** PARAMETERS: **
** sessionMembers Maximum number of participants in the session **
** **
** **
** RETURNS: **
** If no error occurs, the function returns an allocation size for **
** RTCP session. Otherwise it returns NULL. **
** **
**=========================================================================*/
RVAPI
int RVCALLCONV rtcpGetAllocationSize(
IN int sessionMembers)
{
return sizeof(rtcpSession) + ALIGNMENT + sizeof(rtcpInfo) * sessionMembers;
}
/************************************************************************************
* rtcpSetLocalAddress
* description: Set the local address to use for calls to rtcpOpenXXX functions.
* This parameter overrides the value given in rtcpInitEx() for all
* subsequent calls.
* input: ip - Local IP address to use
* output: none.
* return value: Non-negative value on success
* Negative value on failure
***********************************************************************************/
RVAPI
int RVCALLCONV rtcpSetLocalAddress(IN RvUint32 ip)
{
rvRtcpInstance.localIp = ip;
return RV_OK;
}
/*=========================================================================**
** == rtcpOpenFrom() == **
** **
** Opens a new RTCP session in provided buffer. **
** **
** PARAMETERS: **
** ssrc The synchronization source value for the RTCP session. **
** **
** port The UDP port number to be used for the RTCP session. **
** **
** cname A unique name representing the source of the RTP data. **
** Must not be NULL. **
** maxSessionMembers Maximum number of participants in the session **
** **
** buffer pointer to at least rtcpGetAllocationSize byte of memory **
** **
** bufferSize size of the buffer **
** **
** RETURNS: **
** If no error occurs, the function returns a handle for the new **
** RTCP session. Otherwise it returns NULL. **
** **
** COMMENTS: **
** ----------------------------------------------- **
** buffer | rtcpSession |X| participantsArray |X| "mutex" | **
** ----------------------------------------------- **
** X - alignment area **
**=========================================================================*/
RVAPI
HRTCPSESSION RVCALLCONV rtcpOpenFrom(
IN RvUint32 ssrc,
IN RvUint16 port,
IN char * cname,
IN int maxSessionMembers,
IN void * buffer,
IN int bufferSize)
{
rtcpSession* s=(rtcpSession*)buffer;
RvSize_t allocSize=rtcpGetAllocationSize(maxSessionMembers);
int participantsArrayOfs;
RvAddress localAddress;
RvStatus res;
if ((cname == NULL) || (strlen(cname) > MAXSDES) || ((int)allocSize > bufferSize))
{
return NULL;
}
memset(buffer, 0, allocSize);
s->sessionMembers = 0;
s->maxSessionMembers = maxSessionMembers;
s->rtcpRecvCallback = NULL;
s->isAllocated = RV_FALSE;
participantsArrayOfs = RvRoundToSize(sizeof(rtcpSession), ALIGNMENT);
s->participantsArray = (rtcpInfo *) ((char *)s + participantsArrayOfs);
s->participantsArray[0].ssrc = s->myInfo.ssrc = ssrc;
RvAddressConstructIpv4(&localAddress, rvRtcpInstance.localIp, port);
/* Open and bind the socket */
res = RvSocketConstruct(&s->socket, RV_ADDRESS_TYPE_IPV4, RvSocketProtocolUdp);
if (res == RV_OK)
{
res = RvSocketSetBuffers(&s->socket, 8192, 8192);
if (res == RV_OK)
res = RvSocketSetBroadcast(&s->socket, RV_TRUE);
if (res == RV_OK)
res = RvSocketSetBlocking(&s->socket, RV_TRUE);
if (res == RV_OK)
res = RvSocketBind(&s->socket, &localAddress, NULL);
if (res != RV_OK)
RvSocketDestruct(&s->socket, RV_FALSE, NULL);
}
RvAddressDestruct(&localAddress);
if (res != RV_OK)
return NULL;
/* Initialize lock in supplied buffer */
if (RvLockConstruct(&s->lock) != RV_OK)
{
RvSocketDestruct(&s->socket, RV_FALSE, NULL);
return NULL;
}
/* Make sure we wait for RTCP packets */
RvFdConstruct(&s->selectFd, &s->socket);
RvSelectAdd(RvRtpGetSelectEngine(rvRtcpInstance.selectEngine),
&s->selectFd, RvSelectRead, rtcpEventCallback);
setSDES(RTCP_SDES_CNAME, &(s->myInfo.eCName), (RvUint8*)cname, (int)strlen(cname));
return (HRTCPSESSION)s;
}
/*=========================================================================**
** == rtcpOpen() == **
** **
** Opens a new RTCP session. **
** **
** PARAMETERS: **
** ssrc The synchronization source value for the RTCP session. **
** **
** port The UDP port number to be used for the RTCP session. **
** **
** cname A unique name representing the source of the RTP data. **
** Must not be NULL. **
** **
** RETURNS: **
** If no error occurs, the function returns a handle for the new **
** RTCP session. Otherwise it returns NULL. **
** **
**=========================================================================*/
RVAPI
HRTCPSESSION RVCALLCONV rtcpOpen(
IN RvUint32 ssrc,
IN RvUint16 port,
IN char * cname)
{
rtcpSession* s;
int allocSize = rtcpGetAllocationSize(MAXRTPSESSIONMEMBERS);
if (RvMemoryAlloc(NULL, (void**)&s, (RvSize_t)allocSize) != RV_OK)
return NULL;
if((rtcpSession*)rtcpOpenFrom(ssrc, port, cname, MAXRTPSESSIONMEMBERS, (void*)s, allocSize)==NULL)
{
RvMemoryFree(s);
return NULL;
}
s->isAllocated = RV_TRUE;
return (HRTCPSESSION)s;
}
/*=========================================================================**
** == rtcpClose() == **
** **
** Closes 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
RvInt32 RVCALLCONV rtcpClose(
IN HRTCPSESSION hRTCP)
{
rtcpSession *s = (rtcpSession *)hRTCP;
if (hRTCP == NULL)
return RV_ERROR_UNKNOWN;
/* Cancel the timer is one is active */
if (s->isTimerSet)
RvTimerCancel(&s->timer, RV_TRUE);
RvSelectRemove(RvRtpGetSelectEngine(rvRtcpInstance.selectEngine), &s->selectFd);
RvFdDestruct(&s->selectFd);
/* Close the socket */
RvSocketDestruct(&s->socket, RV_FALSE, NULL);
/* Destroy the lock */
RvLockDestruct(&s->lock);
/* free memory allocated for rtcpSession */
if (s->isAllocated)
RvMemoryFree(s);
return RV_OK;
}
/*=========================================================================**
** == rtcpSetRemoteAddress() == **
** **
** Defines the address of the remote peer or of the multicast groop. **
** **
** PARAMETERS: **
** hRTCP The handle of the RTCP session. **
** **
** ip The IP address to which the RTCP packets will be sent. **
** **
** port The UDP port to which the RTCP packets should be sent. **
** **
** RETURNS: **
** A non-negative value upon success, or a negative integer error **
** code. **
** **
**=========================================================================*/
RVAPI
void RVCALLCONV rtcpSetRemoteAddress(
IN HRTCPSESSION hRTCP, /* RTCP Session Opaque Handle */
IN RvUint32 ip, /* target ip address */
IN RvUint16 port) /* target UDP port */
{
rtcpSession *s = (rtcpSession *)hRTCP;
if ((ip != 0) && (port != 0))
{
if (s->remoteAddressSet)
RvAddressDestruct(&s->remoteAddress);
if (RvAddressConstructIpv4(&s->remoteAddress, ip, port) != NULL)
{
s->remoteAddressSet = RV_TRUE;
if (s->isTimerSet == RV_FALSE)
{
RvStatus res;
/* Set a timer */
/*todo: The timeout should be calculated */
res = RvTimerStart(&s->timer, RvRtpGetTimerQueue(rvRtcpInstance.timersQueue),
RV_TIMER_TYPE_PERIODIC, Rv64Multiply(RV_TIME64_NSECPERSEC, RvInt64Const(5)),
rtcpTimerCallback, s);
if (res == RV_OK)
s->isTimerSet = RV_TRUE;
}
}
}
else
{
if (s->remoteAddressSet)
{
RvAddressDestruct(&s->remoteAddress);
s->remoteAddressSet = RV_FALSE;
}
rtcpStop(hRTCP);
}
}
/*=========================================================================**
** == rtcpStop() == **
** **
** Stop RTCP transmisions . **
** **
** PARAMETERS: **
** hRTCP The handle of the RTCP session. **
** **
** RETURNS: **
** A non-negative value upon success, or a negative integer error **
** code. **
** **
**=========================================================================*/
RVAPI
RvInt32 RVCALLCONV rtcpStop(
IN HRTCPSESSION hRTCP) /* RTCP Session Opaque Handle */
{
rtcpSession *s = (rtcpSession *)hRTCP;
/* Cancel the timer if one is active */
if (s->isTimerSet)
{
RvTimerCancel(&s->timer, RV_TRUE);
s->isTimerSet = RV_FALSE;
}
if (s->remoteAddressSet)
RvAddressDestruct(&s->remoteAddress);
s->remoteAddressSet = RV_FALSE;
/* Clear the list*/
memset(s->participantsArray,0, (RvSize_t)(sizeof(rtcpInfo))*(s->sessionMembers));
s->myInfo.collision = 0;
s->myInfo.active = 0;
s->myInfo.timestamp = 0;
memset(&(s->myInfo.eSR),0,sizeof(s->myInfo.eSR));
return RV_OK;
}
/*=========================================================================**
** == rtcpRTPPacketRecv() == **
** **
** Informs the RTCP session that a packet was received in the **
** corresponding RTP session. **
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -