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

📄 frameread.c

📁 linux环境下用纯c写的RTP协议的通用开发库
💻 C
字号:
/* frameread.c - frameread */#include <syn.h>#include <util.h>#include <strings.h>#include <stdlib.h>#include <unistd.h>#include <frame.h>#include <errno.h>#include <util.h>#include <limits.h>#define DEBUG(x)#include <stdio.h>/*------------------------------------------------------------------------ * frameread - read a single frame (times number of channles) from stream * Notes: frameread implicitly begins at "now". *	  Buflen is in bytes. *	  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. *        Tsout gives the media timestamp of the beginning of the data. *          Its initial value has no meaning. It has meaning only on *          success. *        On success, frameread returns the number of bytes copied. *        Frames must be of constant size and duration. *        Frameread copies extra per-packet headers (e.g., as described  *          in RFC 2250) as determined by pparam->fr_dataoffsetfcn. *        Frameread will re-assemble fragmented frames. If fragmentation *          is used, the stream can only be monaureal by the constraints *          laid out in RFC 1890. Only the extra headers in the first  *          fragment of a fragmented frame are returned. The length of *          the buffer for extraheaders is passed in by reference and on *          return contains the number of bytes copied into the buffer. *        All fragments from the same frame must have the same timestamp, *           and must arrive sequentially. *        When a packet contains a fraction of a frame, it may contain  *           no other frames or parts thereof. *------------------------------------------------------------------------ */intframeread(struct synsession *pssn, struct synstream *psstm, struct timespec *time, mediatime_t *tsout, char *buf, int buflen, char *extraheaderbuf, int *extraheaderbuflen, bool *mark){	struct frameparam	*pparam;	struct timespec	now;	struct rtp		*prtp;	struct rtpln		*pln;	mediatime_t		mnow, ts, readfrom, frameduration;	bool			block, flush, aligned;	int			bytesleft, rv, dataoffset, chan, framelen;	char			*pframe;	pparam = (struct frameparam *) psstm->sstm_parameters;	block = (psstm->sstm_readflags & SYN_READ_BLOCK) != 0;	flush = (psstm->sstm_readflags & SYN_READ_FLUSH) != 0;	bzero(time, sizeof(struct timespec));	*tsout = 0;	while (TRUE) {    		/* 		 * Get next packet.		 */		if ((rv = synreadnextpacket(pssn, psstm, &pln)) < 0)			return rv;		prtp = &pln->rln_rtp;		pframe = NULL;		/*		 * Get length (bytes) of any per-packet headers		 */		dataoffset = pparam->fp_dataoffset(prtp, pln->rln_len);		if (dataoffset == ERROR) {			bufpoolfreebuf(pln);			continue;		}		bytesleft = pln->rln_len - RTP_HEADER_LEN(prtp) - dataoffset;		ts = prtp->rtp_time;		/*		 * Obtain current time and convert to media time		 */		clock_gettime(CLOCK_REALTIME, &now);		mnow = timeflatten(timesub(now, psstm->sstm_clkx), psstm->sstm_clkrt) + psstm->sstm_clky;   		readfrom = (flush == TRUE ? tsmax(mnow, psstm->sstm_lastread) : psstm->sstm_lastread);  		/*		 * Find first frame that is 'current'		 */		aligned = pparam->fp_framealigned(prtp, pln->rln_len);		if (aligned == (bool) ERROR) {			bufpoolfreebuf(pln);			continue;		}		if (aligned == TRUE) {			pframe = RTP_DATA(prtp) + dataoffset;			frameduration = pparam->fp_frameduration(pframe, bytesleft);			if (frameduration == ERROR) {				bufpoolfreebuf(pln);				continue;			}			while(!tsgt(ts + frameduration, readfrom)) {  				ts += frameduration;				/*				 * Advance past all frames at this time (1 per channel).				 */				for (chan = 0; chan < pparam->fp_channels; chan++) {					framelen = pparam->fp_framelength(pframe, bytesleft);					if (framelen == ERROR) {						bytesleft = 0;						break; /* from for */					}					pframe += framelen;					bytesleft -= framelen;					if (bytesleft <= 0) 						break; /* from for */				} /* for */				if (bytesleft <= 0) 					break; /* from inner while */				frameduration = pparam->fp_frameduration(pframe, bytesleft);				if (frameduration == ERROR) {					bytesleft = 0; 					break; /* from inner while */				}			} /* while(ts + frameduration <= readfrom) */  			/*			 * Check for no bytes left			 */			if (bytesleft <= 0) {				bufpoolfreebuf(pln);				continue; /* in outter while */			}		}		/* 		 * Check if the data is too new to return		 */		if ((rv = synreadwait(pssn, psstm, pln, ts, now, mnow, time)) < 0)			return rv;		else if (rv == SYN_CONTINUE)			continue;		/*		 * We are now committed to this frame.		 * Decide if it is a full frame or fragment of a frame.		 */		if (pframe != NULL) {			framelen = pparam->fp_framelength(pframe, bytesleft);			if (framelen == ERROR) {				bufpoolfreebuf(pln);				return ERROR;			}		}		if (aligned && bytesleft >= framelen) {			/* 			 * Set mark true if mark bit set AND frame is first in packet.			 */			*mark = prtp->rtp_mark && ((char *) pframe == (char *) prtp + dataoffset);			rv = framereadnonfragmented(pssn, psstm, time, tsout, buf, buflen, extraheaderbuf, extraheaderbuflen, pln, pframe, ts, frameduration, bytesleft);		} else {			/*			 * Reinsert the packet into the queue			 * and invoke framereadfragmented to reassemble the frame.			 */			rtpqinsert(pssn->ssn_session, psstm->sstm_ssrc, pln);			rv = framereadfragmented(pssn, psstm, time, tsout, buf, buflen, extraheaderbuf, extraheaderbuflen, mark, ts);		}		if (rv != ERROR)			return rv;	} /* outter while */}

⌨️ 快捷键说明

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