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

📄 synsyncto.c

📁 linux环境下用纯c写的RTP协议的通用开发库
💻 C
字号:
/*------------------------------------------------------------------------- * synsyncto.c - synsyncto *------------------------------------------------------------------------- */#include <syn.h>#include <strings.h>#include <util.h>#include <math.h>#define DEBUG(x)#ifdef RTPLIB_SYNCHRONIZE/*----------------------------------------------------------------------- * synsyncto - synchronize a group of streams to a particular relation * or each other if relation time equals zero. On success the variables * syncx, syncx specify the "target" relation. * Note that synchronization is experimental and not well-tested. *----------------------------------------------------------------------- */intsynsyncto(struct synsession *pssn, struct cnamelist *pcnl, struct timespec *syncx, struct timespec *syncy){	struct stream		*pstm;	struct synstream	*psstms[128];	struct timespec	        ytime, xtime, delta, zero, maxytime;	mediatime_t	        lastsrts;	int                     mediaoff;	int			i, j, psstmcnt;	bool			adjusted, init = TRUE, external = TRUE;	unsigned int		lastsrntp[2];	external = syncx->tv_sec != 0;  	memset(&maxytime, 0, sizeof(struct timespec));	memset(&zero, 0, sizeof(struct timespec));	for(pstm = pcnl->cn_stream, psstmcnt = 0;	    pstm != NULL && psstmcnt < 128;	    pstm = pstm->stm_cnamenext, psstmcnt++) {		if ((psstms[psstmcnt] = syngetstream(pssn, pstm->stm_ssrc)) == NULL)			continue;		pthread_mutex_lock(&psstms[psstmcnt]->sstm_readmutex);    		/*		 * Check if stream is buffering		 */		if (psstms[psstmcnt]->sstm_buffering == TRUE) {			pthread_mutex_unlock(&psstms[psstmcnt]->sstm_readmutex);			synreleasestream(pssn, psstms[psstmcnt]);			psstms[psstmcnt] = NULL;			continue;		}		rtpctl(pssn->ssn_session, RTP_CTL_STREAM_LOCK, NULL, 0, pstm->stm_ssrc);		rtpctl(pssn->ssn_session, RTP_CTL_STREAM_GETSRTS, (char *) &lastsrts, 0, pstm->stm_ssrc);		rtpctl(pssn->ssn_session, RTP_CTL_STREAM_GETSRNTP, (char *) &lastsrntp, 0, pstm->stm_ssrc);		rtpctl(pssn->ssn_session, RTP_CTL_STREAM_UNLOCK, NULL, 0, pstm->stm_ssrc);		/*		 * Check if stream has yet received a SR.		 */		if (lastsrntp[RTP_NTPINT] == 0) {			pthread_mutex_unlock(&psstms[psstmcnt]->sstm_readmutex);			synreleasestream(pssn, psstms[psstmcnt]);			psstms[psstmcnt] = NULL;			continue;		}		/*		 * Convert NTP format to timespec_t.		 */		xtime.tv_sec = lastsrntp[RTP_NTPINT];		xtime.tv_nsec = (long) (((double) lastsrntp[RTP_NTPFRAC] / pow(2, 32)) * 1000000000);		/*		 * Convert timestamp in last SR to corresponding local time		 */		ytime = timeadd(timeunflatten((lastsrts - psstms[psstmcnt]->sstm_clky), psstms[psstmcnt]->sstm_clkrt), psstms[psstmcnt]->sstm_clkx);		/*		 * Use first NTP time for point on X-axis if no external value		 */		if (external == FALSE && init == TRUE) {			*syncx = xtime;			init = FALSE;		}		/*		 * Xlate relation to syncx, a common point on X-axis		 */		delta = timesub(xtime, *syncx);		ytime = timesub(ytime, delta);		/* 		 * Find maximum y=f_ssrc(syncx) over all ssrc in list.		 * The stream with the maximum is the stream that lags		 * the furthest.		 */		if (timecmp(ytime, maxytime) < 0)			maxytime = ytime;	}	/*	 * Check if the outside clock is ahead	 */	if (external == TRUE) {		if (timecmp(maxytime, *syncy) < 0) {			for (j = 0; j < psstmcnt; j++) 				if (psstms[j] != NULL) {					pthread_mutex_unlock(&psstms[j]->sstm_readmutex);					synreleasestream(pssn, psstms[j]);				}			*syncy = maxytime;			return SYN_EXTERNALAHEAD;		}	}	else		*syncy = maxytime;	DEBUG(printf("Synsync to: External: %s Maxytime %u\n", (external ? "Yes" : "No"), maxytime));	/*	 * Now make the asjustments.	 */	adjusted = FALSE;	for(pstm = pcnl->cn_stream, i = 0; pstm != NULL && i < 128; pstm = pstm->stm_cnamenext, i++) {		if (psstms[i] == NULL)			continue;    		rtpctl(pssn->ssn_session, RTP_CTL_STREAM_LOCK, NULL, 0, pstm->stm_ssrc);		rtpctl(pssn->ssn_session, RTP_CTL_STREAM_GETSRTS, (char *) &lastsrts, 0, pstm->stm_ssrc);		rtpctl(pssn->ssn_session, RTP_CTL_STREAM_GETSRNTP, (char *) &lastsrntp, 0, pstm->stm_ssrc);		rtpctl(pssn->ssn_session, RTP_CTL_STREAM_UNLOCK, NULL, 0, pstm->stm_ssrc);		/*		 * Do same conversions to get y=f_stm(syncx)		 */		xtime.tv_sec = lastsrntp[RTP_NTPINT];		xtime.tv_nsec = (long) (((double) lastsrntp[RTP_NTPFRAC] / pow(2, 32)) * 1000000000);		ytime = timeadd(timeunflatten((lastsrts - psstms[i]->sstm_clky), psstms[i]->sstm_clkrt), psstms[i]->sstm_clkx);		delta = timesub(xtime, *syncx);		ytime = timesub(ytime, delta);		/*		 * Compute amount of change needed		 */		delta = timesub(*syncy, ytime);		if (timecmp(delta, zero) < 0) {			/*			 * Convert to media units and adjust			 */			mediaoff = timeflatten(delta, psstms[i]->sstm_clkrt);			/* 			 * Should there be caps on change?			 */			if (mediaoff > 0) {				adjusted = TRUE;      				psstms[i]->sstm_clky -= mediaoff; 				mediaoff = -mediaoff;				rtppostevent(pssn->ssn_session, EVENT_PARTICIPANT_SYNC, psstms[i]->sstm_ssrc, &mediaoff, sizeof(int));			}		}		pthread_mutex_unlock(&psstms[i]->sstm_readmutex);		synreleasestream(pssn, psstms[i]);	}  	if (adjusted == TRUE)		return SYN_ADJUSTED;	else 		return SYN_NOTADJUSTED;  }#endif /* RTPLIB_SYNCHRONIZE */

⌨️ 快捷键说明

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