www.pudn.com > RTP通用开发库(for Linux).rar > packread.c, change:2000-06-29,size:2685b


/*-------------------------------------------------------------------------
 * packread.c - packread
 *-------------------------------------------------------------------------
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/*------------------------------------------------------------------------
 * packread - read an entire packet from a stream, including RTP header
 * Notes:     Packread returns the next packet. If flush is true
 *		it returns the first packet whose timestamp is <= now,
 *		otherwise, the first packet whose timestamp is <= 
 *		max(now, lastread).
 *            On success packread returns the number of bytes copied.
 *------------------------------------------------------------------------
 */
int
packread(struct synsession *pssn, struct synstream *psstm, struct timespec *time, mediatime_t *ts, char *buf, int buflen)
{

	struct timespec	now, time2;
	struct rtp		*prtp, *prtp2;
	struct rtpln		*pln, *pln2;
	mediatime_t		mnow;
	int			bytescopied, rv;
	bool			block, flush;

	block = (psstm->sstm_readflags & SYN_READ_BLOCK) != 0;
	flush = (psstm->sstm_readflags & SYN_READ_FLUSH) != 0;

	memset(time, 0, sizeof(struct timespec));
	*ts = 0;
  
	while(TRUE) {
    
		/*
		 * Get next packet.
		 */
		if ((rv = synreadnextpacket(pssn, psstm, &pln)) < 0)
			return rv;
    
		prtp = &pln->rln_rtp;

		clock_gettime(CLOCK_REALTIME, &now);
		mnow = timeflatten(timesub(now, psstm->sstm_clkx), psstm->sstm_clkrt) + psstm->sstm_clky;

		/*
		 * Prevent reordering. Do not return a packet 
		 * that is older than the last one we read.
		 */
		if (tslt(prtp->rtp_time, psstm->sstm_lastread)) {
			bufpoolfreebuf(pln);
			continue;
		}
    
		/*
		 * Check next packet's header to see if this packet's too old.
		 */
		if (flush == TRUE) {
			pln2 = rtpqextracthead(pssn->ssn_session, psstm->sstm_ssrc);
			prtp2 = &pln2->rln_rtp;

			if (!tsgt(prtp2->rtp_time, mnow)) {
				bufpoolfreebuf(pln);
				rtpqinsert(pssn->ssn_session, psstm->sstm_ssrc, pln2);
				continue;
			}
			rtpqinsert(pssn->ssn_session, psstm->sstm_ssrc, pln2);
		}

		prtp = &pln->rln_rtp;

		/*
		 * Check if the packet is too new.
		 */
		if ((rv = synreadwait(pssn, psstm, pln, prtp->rtp_time, now, mnow, time)) < 0)
			return rv;
		else if (rv == SYN_CONTINUE)
			continue;

		psstm->sstm_lastread = prtp->rtp_time;

		bytescopied = copypacket(pln, buf, buflen);

		time2 = timeunflatten(prtp->rtp_time - psstm->sstm_clky, psstm->sstm_clkrt);
		time2 = timeadd(time2, psstm->sstm_clkx);
		*time = time2;
		*ts = prtp->rtp_time;

		bufpoolfreebuf(pln);
		return bytescopied;
	}
}