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

📄 sampread.c

📁 linux环境下用纯c写的RTP协议的通用开发库
💻 C
字号:
/*------------------------------------------------------------------------- * sampread.c - sampread *------------------------------------------------------------------------- */#include <syn.h>#include <util.h>#include <strings.h>#include <stdlib.h>#include <unistd.h>#include <sample.h>#include <errno.h>#define DEBUG(x) x#include <stdio.h>/*------------------------------------------------------------------------ * sampread - read from a sample-oriented stream beginning at "now". * Notes: If flush reading begins at `now', else at psstm->sstm_lastread+1 *	  Buflen is in *bytes*. *        Shift the location within the first byte of the beginning of *          the first sample. Shift's initial value has no meaning. Shift *          is necessary for encodings that use < 8 bits / sample. *	  Time gives the local time of the first sample in the data. On *          some errors, time gives the time of next available data. Its  *          initial value has no meaning. *        Ts gives the media timestamp of the beginning of the data. *          Its initial value has no meaning. It has meaning only on *          success. *        Mark is set to true when the first packet read has the marker *          bit set in the RTP header. *        On success, sampread returns the number of samples copied to buf. *          Note that here sample means 1 sample * number of channels. *	    The number of bytes is (samples * samplesize * channels) / 8. *------------------------------------------------------------------------ */intsampread(struct synsession *pssn, struct synstream *psstm, struct timespec *time, mediatime_t *ts, char *buf, int buflen, int *shift, bool *mark){	struct sampparam	*pparam;	struct rtp		*prtp;	struct rtpln		*pln;	struct timespec	now, tmptime;	mediatime_t		endtime, mnow, readfrom;	int			samples, samplestocopy, startdelta, samplescopied = 0;	int			bufsamples, bytescopied, rv;	bool			block, flush;	pparam = (struct sampparam *) psstm->sstm_parameters;	block = (psstm->sstm_readflags & SYN_READ_BLOCK) != 0;	flush = (psstm->sstm_readflags & SYN_READ_FLUSH) != 0;	bzero(time, sizeof(struct timespec));	*ts = 0;	while (TRUE) {    		/*		 * Get the next packet.		 */		if ((rv = synreadnextpacket(pssn, psstm, &pln)) < 0)			return rv;    		prtp = &pln->rln_rtp;		/*		 * Convert local time to corresponding media time.		 */		clock_gettime(CLOCK_REALTIME, &now);		mnow = timeflatten(timesub(now, psstm->sstm_clkx), psstm->sstm_clkrt) + psstm->sstm_clky;		samples = ((pln->rln_len - RTP_HEADER_LEN(prtp)) * 8) / (pparam->sp_samplesz * pparam->sp_channels);		endtime = prtp->rtp_time + samples - 1;		/* 		 * Check if all data in packet is old.		 */		readfrom = (flush == TRUE ? mnow : psstm->sstm_lastread + 1);		if (tslt(endtime, readfrom)) {			bufpoolfreebuf(pln);			continue;		}		/* 		 * Determine where current data begins within packet.		 */		readfrom = tsmax(prtp->rtp_time, readfrom);    		/*		 * Check if data is too new.		 */		if ((rv = synreadwait(pssn, psstm, pln, readfrom, now, mnow, time)) < 0) 			return rv;		else if (rv == SYN_CONTINUE)			continue;    		/*		 * Compute offset from first data to start reading		 * (i.e., where current data begins)		 */		startdelta = (tsgt(readfrom, prtp->rtp_time) ? readfrom - prtp->rtp_time : 0);		*shift = (startdelta * pparam->sp_samplesz * pparam->sp_channels) % 8;		tmptime = timeunflatten(readfrom - psstm->sstm_clky, psstm->sstm_clkrt);		tmptime = timeadd(tmptime, psstm->sstm_clkx);		*time = tmptime;		*ts = readfrom;		*mark = prtp->rtp_mark;		while(TRUE) { 			bufsamples = ((buflen * 8) - (samplescopied == 0 ? *shift : 0)) / (pparam->sp_samplesz * pparam->sp_channels);			samplestocopy = min(samples - startdelta, bufsamples);			bcopy(RTP_DATA(prtp) + ((startdelta * pparam->sp_samplesz * pparam->sp_channels) / 8), buf, align(samplestocopy * pparam->sp_samplesz * pparam->sp_channels, 8) / 8);      			psstm->sstm_lastread = readfrom + samplestocopy - 1;			samplescopied += samplestocopy;      			/* 			 * Check if we've consumed the entire packet.			 */			if (tseq(psstm->sstm_lastread, endtime)) {				bufpoolfreebuf(pln);				bytescopied = align(samplestocopy * pparam->sp_samplesz * pparam->sp_channels, 8) / 8;				buflen -= bytescopied;				buf += bytescopied;				if (buflen == 0)					return samplescopied;					pln = rtpqextracthead(pssn->ssn_session, psstm->sstm_ssrc);				if (pln == NULL)					return samplescopied;				prtp = &pln->rln_rtp;					/*				 * Check for gap between packets.				 */				if (!tseq(prtp->rtp_time, psstm->sstm_lastread + 1)) {					rtpqinsert(pssn->ssn_session, psstm->sstm_ssrc, pln);					return samplescopied;				}					/*				 * Continue with next packet.				 */				samples = ((pln->rln_len - RTP_HEADER_LEN(prtp)) * 8) / (pparam->sp_samplesz * pparam->sp_channels);				endtime = prtp->rtp_time + samples - 1;				readfrom = prtp->rtp_time;				startdelta = 0;			}			else {				rtpqinsert(pssn->ssn_session, psstm->sstm_ssrc, pln);				return samplescopied;			}		}	}}

⌨️ 快捷键说明

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