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


/* rtpqueueapi.c - copypacket, copypacket2, rtpqinit, rtpqdestroy,
 * rtpqlock , rtpqunlock, rtpqclear, rtpqextracthead, rtpqinsert
 */

#include 
#include 
#include 
#include 

/*------------------------------------------------------------------------
 * copypacket - copy packet portion of rtpln to buffer
 *------------------------------------------------------------------------
 */
int
copypacket(struct rtpln *pln, char *buf, int buflen)
{

	buflen = min(buflen, pln->rln_len);
	memcpy(buf, &pln->rln_rtp, buflen);

	return buflen;
}

/*------------------------------------------------------------------------
 * copypacket2 - copy packet header and data into seperate buffers
 * Any header extension treated as data. Amounts copied returned via out
 * variables.
 *------------------------------------------------------------------------
 */
int
copypacket2(struct rtpln *pln, char *headbuf, int *headbuflen, char *databuf, int *databuflen)
{
	
	*headbuflen = min(*headbuflen, RTP_HEADER_LEN(&pln->rln_rtp));
	memcpy(headbuf, &pln->rln_rtp, *headbuflen);

	*databuflen = min(*databuflen, pln->rln_len - 
			  RTP_HEADER_LEN(&pln->rln_rtp));
	memcpy(databuf, RTP_DATA(&pln->rln_rtp), *databuflen);
	
	return OK;
}

/*------------------------------------------------------------------------
 * rtpqinit - initialize a new queue of RTP packetss
 *------------------------------------------------------------------------
 */
int
rtpqinit(struct rtpqueue *pq)
{
	memset(pq, 0, sizeof(struct rtpqueue));
	pthread_mutex_init(&pq->rq_mutex, NULL);
	return OK;
}

/*------------------------------------------------------------------------
 * rtpqdestroy - destroy an RTP packet queue, freeing all packets
 *------------------------------------------------------------------------
 */
int
rtpqdestroy(struct rtpqueue *pq)
{
	if (pthread_mutex_lock(&pq->rq_mutex) != 0)
		return ERROR;

	_rtpqclear(pq);
	pthread_mutex_unlock(&pq->rq_mutex);
	pthread_mutex_destroy(&pq->rq_mutex);
	return OK;
}


/*------------------------------------------------------------------------
 * rtpqlock - lock a stream's queue
 *------------------------------------------------------------------------
 */
int
rtpqlock(struct session *psn, ssrc_t ssrc)
{

	struct stream *pstm;

	pstm = rtpgetstream(psn, ssrc);
	if (pstm == NULL)
		return ERROR;

	if (pthread_mutex_lock(&pstm->stm_queue.rq_mutex) != 0) {
		rtpreleasestream(psn, pstm);
		return ERROR;
	}

	rtpreleasestream(psn, pstm);
	return OK;
}

/*------------------------------------------------------------------------
 * rtpqunlock - unlock a stream's queue
 *------------------------------------------------------------------------
 */
int
rtpqunlock(struct session *psn, ssrc_t ssrc)
{

	struct stream *pstm;

	pstm = rtpgetstream(psn, ssrc);
	if (pstm == NULL)
		return ERROR;

	pthread_mutex_unlock(&pstm->stm_queue.rq_mutex);
	rtpreleasestream(psn, pstm);
	return OK;
}


/*------------------------------------------------------------------------
 * rtpqclear - free all packets from a stream's RTP queue
 *------------------------------------------------------------------------
 */
int
rtpqclear(struct session *psn, ssrc_t ssrc)
{

	struct stream *pstm;
	int		rv;

	pstm = rtpgetstream(psn, ssrc);
	if (pstm == NULL)
		return ERROR;

	if (pthread_mutex_unlock(&pstm->stm_queue.rq_mutex) != 0) {
		rtpreleasestream(psn, pstm);
		return ERROR;
	}

	rv = _rtpqclear(&pstm->stm_queue);
	pthread_mutex_unlock(&pstm->stm_queue.rq_mutex);

	rtpreleasestream(psn, pstm);
	return rv;
}

/*------------------------------------------------------------------------
 * rtpqextracthead - remove and return pointer to first packet in queue
 *------------------------------------------------------------------------
 */
struct rtpln *
rtpqextracthead(struct session *psn, ssrc_t ssrc)
{
	
	struct stream	*pstm;
	struct rtpln	*pln;
      
	pstm = rtpgetstream(psn, ssrc);
	if (pstm == NULL)
		return NULL;
						
	if (pthread_mutex_lock(&pstm->stm_queue.rq_mutex) != 0) {
		rtpreleasestream(psn, pstm);
		return NULL;
	}

	pln = rtpqextract(&pstm->stm_queue, pstm->stm_queue.rq_head);
	pthread_mutex_unlock(&pstm->stm_queue.rq_mutex);
	rtpreleasestream(psn, pstm);
	return pln;
}

/*------------------------------------------------------------------------
 * rtpqinsert - insert a packet into queue
 *------------------------------------------------------------------------
 */
int
rtpqinsert(struct session *psn, ssrc_t ssrc, struct rtpln *pln)
{

	struct stream *pstm;
	int		rv;

	pstm = rtpgetstream(psn, ssrc);
	if (pstm == NULL)
		return ERROR;

	if (pthread_mutex_lock(&pstm->stm_queue.rq_mutex) != 0) {
		rtpreleasestream(psn, pstm);
		return ERROR;
	}

	rv = _rtpqinsert(&pstm->stm_queue, pln, NULL);
	pthread_mutex_unlock(&pstm->stm_queue.rq_mutex);
	rtpreleasestream(psn, pstm);

	return rv;
}