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


/*-------------------------------------------------------------------------
 * synbufspan.c - synbufspan
 *-------------------------------------------------------------------------
 */

#include 
#include 

/*-------------------------------------------------------------------------
 * synbufspan - returns the media timestamps of the first and last data
 * in a synstream's RTP data queue.
 *-------------------------------------------------------------------------
 */
int
synbufspan(struct synsession *pssn, struct synstream *psstm, mediatime_t *begin, mediatime_t *end)
{
  
	struct stream         *pstm;
	struct rtpln          *pln;
	struct rtp            *prtp;
	int                   samples;
	struct sampparam      *psampparam;
  
	pstm = rtpgetstream(pssn->ssn_session, psstm->sstm_ssrc);
    
	if (pstm == NULL)
		return ERROR;
    
	if (rtpqlock(pssn->ssn_session, psstm->sstm_ssrc) == ERROR) {
		rtpreleasestream(pssn->ssn_session, pstm);
		return ERROR;
	}
  
	if (pstm->stm_queue.rq_head == NULL) {
		rtpqunlock(pssn->ssn_session, psstm->sstm_ssrc);
		rtpreleasestream(pssn->ssn_session, pstm);
		*begin = *end = 0;
		return OK;
	}
  
	*begin = pstm->stm_queue.rq_head->rln_rtp.rtp_time;
  
	switch(psstm->sstm_type) {
    
	case SYN_STREAMTYPE_FRAME:
	case SYN_STREAMTYPE_PACKET:
		/*
		 * For packet streams we cannot compute the exact
		 * span. We return only the difference between 
		 * the timestamp of the first and last packets 
		 * in the queue.
		 * 
		 * For frame streams it is possible to decode the 
		 * length of the last frame of the last packet
		 * (if all fragments of a fragmented frame have 
		 * been received). However, frame streams are
		 * currnetly treated the same as raw packet streams
		 * by synbyfspan.
		 */
		*end = pstm->stm_queue.rq_tail->rln_rtp.rtp_time;
		break;
    
	case SYN_STREAMTYPE_SAMPLE:
		/*
		 * For sample streams we compute the the exact span.
		 */
		psampparam = (struct sampparam *) psstm->sstm_parameters;
		pln = pstm->stm_queue.rq_tail;
		prtp = &pln->rln_rtp;
		samples = ((pln->rln_len - RTP_HEADER_LEN(prtp)) * 8)
			/ (psampparam->sp_samplesz * psampparam->sp_channels);   
		*end = prtp->rtp_time + samples - 1;
		break;      
	}
  
	rtpqunlock(pssn->ssn_session, psstm->sstm_ssrc);
	rtpreleasestream(pssn->ssn_session, pstm);
	return OK;
}