www.pudn.com > RTP通用开发库(for Linux).rar > rtcpbye.c


/*-------------------------------------------------------------------------
 * rtcpbye.c - rtcpbye
 *-------------------------------------------------------------------------
 */

#include 
#include 
#include 
#include 
#include 
#include 

/*------------------------------------------------------------------------
 * rtcpbye - process an incoming RTCP bye message
 *------------------------------------------------------------------------
 */
int
rtcpbye(struct session *psn, struct rtcp *prtcp)
{

	struct stream		*pstm;
	ssrc_t		*p, ssrc;
	int			i, eventdatalen;
	char			eventdata[sizeof(ssrc_t) + 256];
	struct byereason	*preason;

	if (prtcp->rtcp_type != RTCP_BYE) 
		return ERROR;
  
	/*
	 * Look for a reason string.
	 */
	if (prtcp->rtcp_length > prtcp->rtcp_count) {
		preason = (struct byereason *) (prtcp->rtcp_data + prtcp->rtcp_count * sizeof(ssrc_t));
		eventdatalen = preason->bye_length + 1;
		memcpy(eventdata, preason->bye_reason, preason->bye_length);
		eventdata[preason->bye_length] = '\0';
	} else
		eventdatalen = 0;

	/*
	 * Iterate through list of synchronization 
	 * source identifiers in the bye message.
	 */
	for (i = 0, p = (unsigned int *) prtcp->rtcp_data;
	     i < prtcp->rtcp_count;
	     i++, p++) {

		ssrc = ntohl(*p);
		pstm = rtpgetstream(psn, ssrc);
		if (pstm != NULL) {
			if (!RTP_INACTIVE(pstm->stm_inactive)) {
				
				/*
				 * Mark the stream as inactive,
				 * cleanup if necessary, and post
				 * event informing of the stream's
				 * exit containing the reason string
				 * as data.
				 */
				pstm->stm_inactive = RTP_BYERECEIVED;
				rtpstreamcleanup(psn, pstm);
				rtppostevent(psn, EVENT_RTCP_BYE, ssrc, eventdata, eventdatalen);
			}
			rtpreleasestream(psn, pstm);
		}
	}
	return OK;
}