⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtpopen.c

📁 linux环境下用纯c写的RTP协议的通用开发库
💻 C
字号:
/*------------------------------------------------------------------------- * rtpopen.c - rtpopen, rtpopensockets *------------------------------------------------------------------------- */#include <netinet/in.h>#include <sys/types.h>#include <stdio.h>#include <stdlib.h>#include <sys/socket.h>#include <hash.h>#include <strings.h>#include <string.h>#include <unistd.h>#include <time.h>#include <rtp.h>#include <rtcp.h>#include <util.h>#include <arpa/inet.h>#include <pthread.h>/*------------------------------------------------------------------------ * rtpopen - open a new RTP session, allocate resources and create state *------------------------------------------------------------------------ */struct session *rtpopen(struct in_addr session, int port, int bpbufsz, int bpbufcnt){	struct session *psn;	int            rv, packetsneeded;	psn = (struct session *) malloc(sizeof(struct session));	if (psn == NULL)		return NULL;  	memset(psn, 0, sizeof(struct session));	psn->sn_rtpfd = psn->sn_rtcpfd = -1;	psn->sn_ssrcs = htnew(RTP_SSRCHTSZ, hashunsignedint, unsignedinteq, NULL, (void(*)(void *)) rtpdestroystream);	psn->sn_cnames = htnew(RTP_CNAMEHTSZ, hashstring, (int(*)(unsigned int, unsigned int))strcasecmp, (void(*)(unsigned int))free, (void(*)(void *))free);	psn->sn_cyclesources = (ssrc_t *) malloc(sizeof(ssrc_t) * RTCP_RRMAXRBLOCKS);	packetsneeded = RTCP_RRMAXRBLOCKS / RTCP_MAXRBLOCKS + ((RTCP_RRMAXRBLOCKS % RTCP_MAXRBLOCKS) != 0);	psn->sn_cyclebuf = (char *) malloc(RTCP_RRMAXRBLOCKS * sizeof(struct rblock) + packetsneeded * (RTCP_HEADERSZ + sizeof(ssrc_t)));	rv = bufpoolinit(&psn->sn_bpool, bpbufsz, bpbufcnt);  	pthread_cond_init(&psn->sn_cond, NULL);	pthread_mutex_init(&psn->sn_mutex, NULL);	pthread_mutex_init(&psn->sn_getstreammutex, NULL);	pthread_mutex_init(&psn->sn_cnamemutex, NULL);	pthread_mutex_init(&psn->sn_rtpthrmutex, NULL);	pthread_mutex_init(&psn->sn_rtcpthrmutex, NULL);	pthread_mutex_init(&psn->sn_rtcpcyclethrmutex, NULL);	psn->sn_addr = session;	psn->sn_port = port;	psn->sn_bw = RTP_DEFAULT_SESSIONBW;	psn->sn_ssrc = rtpmkssrc(NULL);	psn->sn_autocleanup = TRUE;	if (rtpopensockets(psn, session, port) == ERROR ||	    psn->sn_ssrcs == NULL ||	    psn->sn_cnames == NULL ||	    psn->sn_cyclesources == NULL ||	    psn->sn_cyclebuf == NULL ||	    rv == ERROR) {		rtpclose(psn);		return NULL;	}  	return psn;}/*------------------------------------------------------------------------ * rtpopensockets - open socket for RTP and RTCP datagrams *------------------------------------------------------------------------ */intrtpopensockets(struct session *psn, struct in_addr session, int port){	struct sockaddr_in	saddr;	struct ip_mreq	        mreq;	unsigned char		loop;	int			reuse;	unsigned char		ttl;	psn->sn_rtpfd = socket(AF_INET, SOCK_DGRAM, 0);	psn->sn_rtcpfd = socket(AF_INET, SOCK_DGRAM, 0);  	if (psn->sn_rtpfd < 0 || psn->sn_rtcpfd < 0) {		return ERROR;	}	memset(&saddr, 0, sizeof(struct sockaddr_in));	saddr.sin_family = AF_INET;	if(IN_CLASSD(ntohl(session.s_addr))) {		saddr.sin_addr = session;	}	else {		saddr.sin_addr.s_addr = htonl(INADDR_ANY);	}	if (IN_CLASSD(ntohl(session.s_addr))) {		reuse = 1;		if (setsockopt(psn->sn_rtpfd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) < 0) {			close(psn->sn_rtpfd);			close(psn->sn_rtcpfd);			return ERROR;		}    		if (setsockopt(psn->sn_rtcpfd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) < 0) {			close(psn->sn_rtpfd);			close(psn->sn_rtcpfd);			return ERROR;		}	}  	saddr.sin_port = htons(port);  	if (bind(psn->sn_rtpfd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in)) < 0) {		close(psn->sn_rtpfd);		close(psn->sn_rtcpfd);		return ERROR;	}  	saddr.sin_port = htons(port + 1);	if (bind(psn->sn_rtcpfd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in)) < 0) {		close(psn->sn_rtpfd);		close(psn->sn_rtcpfd);		return ERROR;	}	psn->sn_rtcpto = saddr;	if (!IN_CLASSD(ntohl(session.s_addr)))		psn->sn_rtcpto.sin_addr.s_addr = RTP_INADDRUNINITIALIZED;	if (IN_CLASSD(ntohl(session.s_addr))) {		mreq.imr_multiaddr = session;		mreq.imr_interface.s_addr = htonl(INADDR_ANY);    		if (setsockopt(psn->sn_rtpfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(struct ip_mreq)) < 0) {			close(psn->sn_rtpfd);			close(psn->sn_rtcpfd);			return ERROR;		}		if (setsockopt(psn->sn_rtcpfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(struct ip_mreq)) < 0) {			close(psn->sn_rtpfd);			close(psn->sn_rtcpfd);			return ERROR;		}		/*		 * Disable loopback on RTCP socket so we don't want to hear ourselves.		 * This isn't done for the RTP socket because this implementation		 * assumes no sending.		 */		loop = 0;		if (setsockopt(psn->sn_rtcpfd, IPPROTO_IP, IP_MULTICAST_LOOP, 			       (char *) &loop, sizeof(loop)) < 0) {			close(psn->sn_rtpfd);			close(psn->sn_rtcpfd);			return ERROR;		}    		/* 		 * Set TTL.		 * This isn't done for the RTP socket because this implementation		 * assumes no sending.		 */		ttl = RTP_DEFAULT_SESSIONTTL;		if (setsockopt(psn->sn_rtcpfd, IPPROTO_IP, IP_MULTICAST_TTL, 			       (char *) &ttl, sizeof(ttl)) < 0) {			close(psn->sn_rtpfd);			close(psn->sn_rtcpfd);			return ERROR;		}	}	return OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -