📄 rtcp.c
字号:
{ RvStatus res; res = RvSelectDestruct(rvRtcpInstance.selectEngine, 1024); RvCBaseEnd(); rvRtcpInstance.timesInitialized--; return res;}RVAPIRvInt32 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. **** ****=========================================================================*/RVAPIint 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 ***********************************************************************************/RVAPIint 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 ****=========================================================================*/RVAPIHRTCPSESSION 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 status; 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 */ status = RvSocketConstruct(RV_ADDRESS_TYPE_IPV4, RvSocketProtocolUdp, logMgr, &s->socket); if (status == RV_OK) { RvSocketSetBuffers(&s->socket, 8192, 8192, logMgr); status = RvSocketSetBroadcast(&s->socket, RV_TRUE, logMgr); if (status == RV_OK) status = RvSocketSetBlocking(&s->socket, RV_TRUE, logMgr); if (status == RV_OK) status = RvSocketBind(&s->socket, &localAddress, NULL, logMgr); if (status != RV_OK) RvSocketDestruct(&s->socket, RV_FALSE, NULL, logMgr); } RvAddressDestruct(&localAddress); if (status != RV_OK) return NULL; /* Initialize lock in supplied buffer */ if (RvLockConstruct(logMgr, &s->lock) != RV_OK) { RvSocketDestruct(&s->socket, RV_FALSE, NULL, logMgr); return NULL; } /* Make sure we wait for RTCP packets */ RvFdConstruct(&s->selectFd, &s->socket, logMgr); status = RvSelectGetThreadEngine(logMgr, &s->selectEngine); if ((status != RV_OK) || (s->selectEngine == NULL)) s->selectEngine = rvRtcpInstance.selectEngine; RvSelectAdd(s->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. **** ****=========================================================================*/RVAPIHRTCPSESSION RVCALLCONV rtcpOpen( IN RvUint32 ssrc, IN RvUint16 port, IN char * cname){ rtcpSession* s; int allocSize = rtcpGetAllocationSize(MAXRTPSESSIONMEMBERS); if (RvMemoryAlloc(NULL, (RvSize_t)allocSize, logMgr, (void**)&s) != RV_OK) return NULL; if((rtcpSession*)rtcpOpenFrom(ssrc, port, cname, MAXRTPSESSIONMEMBERS, (void*)s, allocSize)==NULL) { RvMemoryFree(s, logMgr); 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. **** ****=========================================================================*/RVAPIRvInt32 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_TIMER_CANCEL_WAIT_FOR_CB); RvSelectRemove(s->selectEngine, &s->selectFd); RvFdDestruct(&s->selectFd); /* Close the socket */ RvSocketDestruct(&s->socket, RV_FALSE, NULL, logMgr); /* Destroy the lock */ RvLockDestruct(&s->lock, logMgr); /* free memory allocated for rtcpSession */ if (s->isAllocated) RvMemoryFree(s, logMgr); return RV_OK;}/*=========================================================================**** == rtcpSetRemoteAddress() == **** **** Defines the address of the remote peer or of the multicast group. **** **** 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. **** ****=========================================================================*/RVAPIvoid 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) { RvTimerQueue *timerQ = NULL; RvStatus status; /* Find the timer queue we are working with */ status = RvSelectGetTimeoutInfo(s->selectEngine, NULL, &timerQ); if (status != RV_OK) timerQ = NULL; if (timerQ == NULL) timerQ = rvRtcpInstance.timersQueue; /* Set a timer */ /*todo: The timeout should be calculated */ status = RvTimerStart(&s->timer, timerQ, RV_TIMER_TYPE_PERIODIC, RvInt64Const(1, 1, 0x2a05f200) /* 5 seconds */, rtcpTimerCallback, s); if (status == RV_OK) s->isTimerSet = RV_TRUE; } } } else { if (s->remoteAddressSet) { RvAddressDestruct(&s->remoteAddress); s->remoteAddressSet = RV_FALSE; } rtcpStop(hRTCP); }}/*=========================================================================**** == rtcpStop() == **** **** Stop RTCP transmissions . **** **** PARAMETERS: **** hRTCP The handle of the RTCP session. **** **** RETURNS: **** A non-negative value upon success, or a negative integer error **** code. **** ****=========================================================================*/RVAPIRvInt32 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_TIMER_CANCEL_WAIT_FOR_CB); 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 + -