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


/*-------------------------------------------------------------------------
 * synctl.c - synctl
 *-------------------------------------------------------------------------
 */

#include 
#include 
#include 

/*------------------------------------------------------------------------
 * synctl - miscelaneous functions for synch layer session
 * Values are passed in and out by reference. The caller must ensure
 * that a pointer to the correct type (e.g., a bool * when expected)
 * is passed.
 *------------------------------------------------------------------------
 */
int
synctl(struct synsession *pssn, int command, char *arg, ssrc_t ssrc)
{

	struct synstream *psstm;
	mediatime_t      begin, end;
#ifdef RTPLIB_SYNCHRONIZE
	int              i;
#endif /* RTPLIB_SYNCHRONIZE */

	/*
	 * Commands that do not refer to a particular stream.
	 */
	switch(command) {

	case SYN_CTL_GETRTPSESSION:
		*((struct session **) arg) = pssn->ssn_session;
		return OK;

#ifdef RTPLIB_SYNCHRONIZE
	case SYN_CTL_ADDSYNCFD:
	case SYN_CTL_REMSYNCFD:

		if (pthread_mutex_lock(&pssn->ssn_mutex) != 0)
			return ERROR;
 
		if (command == SYN_CTL_ADDSYNCFD) {   
			for (i = 0; i < SYN_FDCNT; i++)
				if (pssn->ssn_syncfds[i] == SYN_BADFD)
					pssn->ssn_syncfds[i] = *((int *) arg);
		}
		if (command == SYN_CTL_REMSYNCFD) {
			for (i = 0; i < SYN_FDCNT; i++)
				if (pssn->ssn_syncfds[i] == *((int *) arg))
					pssn->ssn_syncfds[i] = SYN_BADFD;
		}

		/* wake receive thread */
		pthread_mutex_lock(&pssn->ssn_recvthrmutex);
		if (pssn->ssn_recvthrstat == THR_RUNNING) {
			pthread_kill(pssn->ssn_recvthr, SIGHUP);
			pthread_mutex_unlock(&pssn->ssn_mutex);
		}
		pthread_mutex_unlock(&pssn->ssn_recvthrmutex);
		return OK;
#endif /* RTPLIB_SYNCHRONIZE */
	} /* switch(command) */

	/*
	 * Commands that refer to a particular stream.
	 */
	psstm = syngetstream(pssn, ssrc);
	if (psstm == NULL)
		return ERROR;

	switch(command) {

	case SYN_CTL_STREAM_GETREADFLAGS:
		*((int *) arg) = psstm->sstm_readflags;
		break;

	case SYN_CTL_STREAM_SETREADFLAGS:
		psstm->sstm_readflags = *((int *) arg);
		break;

	case SYN_CTL_STREAM_ISBUFFERING:
		*((bool *) arg) = psstm->sstm_buffering;
		break;

	case SYN_CTL_STREAM_GETCLKRT:
		*((int *) arg) = psstm->sstm_clkrt;
		break;

	case SYN_CTL_STREAM_GETTYPE:
		*((int *) arg) = psstm->sstm_type;
		break;

	case SYN_CTL_STREAM_GETLASTREAD:
		*((mediatime_t *) arg) = psstm->sstm_lastread;
		break;

	case SYN_CTL_STREAM_GETPARAM:
		*((void **) arg) = psstm->sstm_parameters;
		break;
    
	case SYN_CTL_STREAM_GETLEEWAY:
		/*
		 * Convert timespec_t to microsec.
		 */
		*((unsigned int *) arg) = (psstm->sstm_leewayts.tv_sec * 100000) + (psstm->sstm_leewayts.tv_nsec / 1000);
		break;
    
	case SYN_CTL_STREAM_SETLEEWAY:
		/*
		 * Convert from microsec to media time ticks.
		 */
		psstm->sstm_leeway = (mediatime_t) (((double) *((mediatime_t *) arg) * (double) psstm->sstm_clkrt) / 1000000.0);

		/*
		 * Convert from microsec to timespec
		 */
		psstm->sstm_leewayts = timeunflatten(*((mediatime_t *) arg), 1000000);
		break;

	case SYN_CTL_STREAM_GETJITTHRESH:
		*((mediatime_t *) arg) = psstm->sstm_jitthresh;
		break;

	case SYN_CTL_STREAM_SETJITTHRESH:
		psstm->sstm_jitthresh = *((mediatime_t *) arg);
		break;
    
	case SYN_CTL_STREAM_GETBUFSPAN:
		if (synbufspan(pssn, psstm, &begin, &end) == ERROR) {
			synreleasestream(pssn, psstm);
			return ERROR;
		}
		*((unsigned int *) arg) = end - begin;
		break;
	}
  
	synreleasestream(pssn, psstm);
	return OK;
}