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


/*-------------------------------------------------------------------------
 * rtp.h - RTP_HEADER_LEN, RTP_DATA, RTP_INACTIVE, RTP_CNAMEPRESENT,
 * RTP_DATASEEN
 *-------------------------------------------------------------------------
 */
#ifndef RTP_H
#define RTP_H

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

#if defined(LINUX)
#include 
#elif defined(SOLARIS)
#include 
#endif

/* RTP Constants */
#define RTP_CURRVERS		2          /* current version number */
#define RTP_HEADERMINLEN	12         /* min header length      */
#define RTP_MAXDROPOUT		3000       /* for rtpupdateseq()     */
#define RTP_MAXMISORDER		100        /* for rtpupdateseq()     */
#define RTP_MINSEQUENTIAL	2          /* for rtpupdateseq()     */
#define RTP_SEQMOD		(1 << 16)  /* for rtpupdateseq()     */

/* RTP Macros */
#define RTP_HEADER_LEN(prtp)	(RTP_HEADERMINLEN + \
				((prtp)->rtp_cc * sizeof(ssrc_t)))
#define RTP_DATA(prtp)		((char *)prtp + RTP_HEADER_LEN(prtp))

/* Structure for RTP packet */
struct rtp {
#if __BYTE_ORDER == __LITTLE_ENDIAN || defined(_LITTLE_ENDIAN)
  unsigned int	rtp_cc:4;	 /* source count			*/
  unsigned int	rtp_ext:1;	 /* extension flag			*/
  unsigned int	rtp_pad:1;	 /* padding flag			*/
  unsigned int	rtp_ver:2;	 /* version				*/
  unsigned int	rtp_payload:7;	 /* payload type			*/
  unsigned int	rtp_mark:1;	 /* marker flag				*/
#elif __BYTE_ORDER == __BIG_ENDIAN || defined(_BIG_ENDIAN)
  unsigned int	rtp_ver:2;	 /* version				*/
  unsigned int	rtp_pad:1;	 /* padding flag			*/
  unsigned int	rtp_ext:1;	 /* extension flag			*/
  unsigned int	rtp_cc:4;	 /* source count			*/
  unsigned int	rtp_mark:1;	 /* marker flag				*/
  unsigned int	rtp_payload:7;	 /* payload type			*/
#endif
  seq_t		rtp_seq;	 /* sequence number			*/
  mediatime_t	rtp_time;	 /* timestamp				*/
  ssrc_t	rtp_ssrc;	 /* synchronization source identifier	*/
  char		rtp_data[1];	 /* beginning of header extnsn or data  */
};

/* Structure for linked list node for RTP packets */
struct rtpln {
  int		rln_len;	/* total length of packet	*/
  unsigned int	rln_seq;	/* extended sequence number	*/
  struct rtpln	*rln_next;	/* older packer			*/
  struct rtpln	*rln_prev;	/* newer packet			*/
  struct rtp	rln_rtp;	/* RTP packet			*/
};

/* Structure for queue of struct rtplns */
struct rtpqueue {
  struct rtpln  *rq_head;       /* oldest packet in queue       */
  struct rtpln  *rq_tail;       /* newest packet in queue       */
  int           rq_len;         /* sum of packet sizes in queue */
  pthread_mutex_t rq_mutex;     /* mutex to lock queue          */
};

/* Stream Constants */
#define RTP_BYERECEIVED			-1
#define RTP_TIMEDOUT			-2
#define RTP_PAYLOADUNINITIALIZED	-1
#define RTP_INADDRUNINITIALIZED		INADDR_ANY
#define RTP_INFINITEINACTIVETHRESH	-1
#define RTP_DEFAULT_INACTIVETHRESH	5
#define RTP_NTPINT			1
#define RTP_NTPFRAC			0

/* Stream macros */
#define RTP_INACTIVE(v)		(v == RTP_BYERECEIVED || v == RTP_TIMEDOUT)
#define RTP_CNAMEPRESENT(pstm)	(pstm->stm_cname[0] != 0)
#define RTP_DATASEEN(pstm)	(pstm->stm_packets > pstm->stm_recprior)

/* State structure for stream */
struct stream {
  pthread_mutex_t 
                stm_mutex;	/* mutex for locking stream structure	*/
  ssrc_t	stm_ssrc;	/* synchronization source identifier	*/
  bool		stm_zombie;	/* stream marked for removal when true	*/
  unsigned int	stm_clkrt;	/* participant's clockrate in Hz	*/
  int		stm_payload;	/* stream's payload type		*/
  bool		stm_enqueue;	/* switch to turn on data enqueueing	*/
  struct sockaddr_in
		stm_ip;		/* partipant's IP address		*/
  int		stm_refcnt;	/* reference count			*/
  struct rtpqueue 
                stm_queue;      /* queue of RTP packets                 */
  bool		stm_mark;	/* source marked for rblock generation	*/
  int		stm_inactive;	/* number of inactive cycles or status	*/
  int		stm_inactthresh;/* number of inactive cycles to timeout */
  double	stm_jitter;	/* jitter measure			*/ 
  unsigned int	stm_packets;	/* cumulative packets received		*/
  unsigned int	stm_probation;	/* sequential pkts to validate stream	*/
  seq_t		stm_firstseq;	/* first sequence number received	*/
  seq_t		stm_hiseq;	/* greatest seq number recently received*/
  unsigned int	stm_badseq;	/* bad sequence number (RFC 1889)	*/ 
  unsigned int	stm_roll;	/* number of `roll-overs'		*/
  unsigned int	stm_recprior;	/* value saved from last RTCP cycle	*/
  unsigned int	stm_expprior;	/* value saved from last RTCP cycle	*/
  mediatime_t	stm_lastts;	/* last timestamp for jitter		*/
  struct timespec	
                stm_lastrec;	/* time last packet received for jitter */
  unsigned int	stm_lastntp[2];	/* NTP timestamp of last SR (low, high)	*/
  struct timespec
                stm_lastsr;	/* my time last sender report received	*/
  mediatime_t	stm_lastsrts;	/* RTP timestamp in last sender report	*/
  struct stream *stm_cnamenext; /* next participant with same cname	*/
  struct stream *stm_cnameprev; /* previous participant with same cname	*/
  char		stm_cname[256];	/* canonical name			*/
  char		stm_name[256];	/* participant's name			*/
  char		stm_email[256];	/* participant's email address		*/
  char		stm_phone[256];	/* participant's phone			*/
  char		stm_loc[256];	/* participant's location		*/
  char		stm_tool[256];	/* participant's tool name		*/
  char		stm_note[256];	/* participant's note			*/
  char		stm_priv[256];	/* private data				*/
};

struct cnamelist {
  struct stream  *cn_stream;
};

/* Session constants */
#define RTP_CNAMEHTSZ	             27
#define RTP_SSRCHTSZ	             27
#define RTP_DEFAULT_SESSIONBW        16000
#define RTP_DEFAULT_SESSIONTTL       16
#define RTP_MAXEVENTQUEUES           16

/* Commands for rtpctl */
#define RTP_CTL_ADDEVENTQUEUE        1
#define RTP_CTL_REMEVENTQUEUE        2
#define RTP_CTL_SETTTL               3
#define	RTP_CTL_SETBW                4
#define RTP_CTL_SETCLEANUP           5
#define RTP_CTL_RTCPCYCLETHREAD      6
#define RTP_CTL_RTPRECVTHREAD        7
#define RTP_CTL_RTCPRECVTHREAD       8
#define RTP_CTL_STREAM_GETENQUEUE    9
#define RTP_CTL_STREAM_GETCLKRT      10
#define RTP_CTL_STREAM_SETCLKRT      11
#define RTP_CTL_STREAM_GETPT         12
#define RTP_CTL_STREAM_GETQLEN       15
#define RTP_CTL_STREAM_GETINACTIVE   16
#define RTP_CTL_STREAM_GETJITTER     17
#define RTP_CTL_STREAM_GETPACKETCNT  18
#define RTP_CTL_STREAM_GETROLLOVERS  19 
#define RTP_CTL_STREAM_GETPROBATION  20
#define RTP_CTL_STREAM_GETCNAME      21
#define RTP_CTL_STREAM_GETNAME       22
#define RTP_CTL_STREAM_GETEMAIL      23 
#define RTP_CTL_STREAM_GETPHONE      24
#define RTP_CTL_STREAM_GETTOOL       25
#define RTP_CTL_STREAM_GETNOTE       26
#define RTP_CTL_STREAM_GETPRIV       27
#define RTP_CTL_STREAM_GETINACTTHR   28
#define RTP_CTL_STREAM_SETINACTTHR   29
#define RTP_CTL_STREAM_GETSRTS       30
#define RTP_CTL_STREAM_GETSRNTP      31
#define RTP_CTL_STREAM_LOCK          32
#define RTP_CTL_STREAM_UNLOCK        33
#define RTP_CTL_STREAM_NULL          34
#define RTP_CTL_STREAM_EXISTS        RTP_CTL_STREAM_NULL

struct session {
  struct in_addr       sn_addr; /* session address                      */
  int           sn_port;        /* session port                         */
  pthread_mutex_t sn_mutex;     /* mutex to lock session structure      */
  pthread_cond_t  sn_cond;      /* session condition variable           */
  pthread_mutex_t sn_cnamemutex;/* mutex to lock cname threadings       */
  pthread_mutex_t 
              sn_getstreammutex;/* mutex for rtpgetstream function      */
  unsigned int	sn_ssrc;	/* my synchronization source identifier	*/
  int           sn_bw;          /* approx session bandwidth in bits/sec	*/
  bool		sn_autocleanup;	/* action to take on stream expiration	*/
  int		sn_rtpfd;	/* file descriptor for RTP		*/
  int		sn_rtcpfd;	/* file descriptor for RTCP		*/
  struct ht	*sn_ssrcs;	/* ssrc -> stream * hashtable		*/
  struct ht     *sn_cnames;     /* cname -> stream * hashtable		*/
  struct sockaddr_in
                sn_rtcpto;	/* destination for RTCP packets		*/
  int           sn_avgrtcp;     /* RTCP len for interval computation	*/
  struct eventqueue
                *sn_eventqs[RTP_MAXEVENTQUEUES];
                                /* event queues                         */
  pthread_t	sn_rtcpcyclethr;/* thread to perform RTCP cycle dutes	*/
  int           
            sn_rtcpcyclethrstat;/* state of RTCP cycle thread           */
  pthread_mutex_t 
           sn_rtcpcyclethrmutex;/* mutex for cycle thread state         */
  pthread_t	sn_rtpthr;	/* thread to process RTP packets	*/
  int           sn_rtpthrstat;  /* RTP receive thread state             */
  pthread_mutex_t 
                sn_rtpthrmutex; /* mutex for RTP receive thread state   */
  pthread_t	sn_rtcpthr;	/* thread to process RTCP packets	*/
  int           sn_rtcpthrstat; /* RTCP receive thread state            */
  pthread_mutex_t
               sn_rtcpthrmutex; /* mutex for RTCP receive thread state  */
  struct bufpool sn_bpool;      /* pool of buffers for RTP packets      */
  ssrc_t        
              *sn_cyclesources; /* memory for rtcpcycle() to hold ssrcs */
  char          *sn_cyclebuf;   /* memory for rtcpcycle() to make RR    */
};



/* API Calls */
struct session	*rtpopen(struct in_addr, int, int, int);
int rtpclose(struct session *);
int rtpstreamon(struct session *, ssrc_t, unsigned int);
int rtpstreamoff(struct session *, ssrc_t);
int rtpctl(struct session *, int, char *, int, ssrc_t);
int rtpsources(struct session *, ssrc_t *, int);

/* API queue functions */
int rtpqlock(struct session *, ssrc_t ssrc);
int rtpqunlock(struct session *, ssrc_t ssrc);
struct rtpln *rtpqextracthead(struct session *, ssrc_t ssrc);
int rtpqinsert(struct session *, ssrc_t, struct rtpln *);
int rtpqclear(struct session *, ssrc_t);
int rtpqinit(struct rtpqueue *);
int rtpqdestroy(struct rtpqueue *);

/* utility */
int copypacket(struct rtpln *, char *, int);
int copypacket2(struct rtpln *, char *, int *, char *, int *);

/* Internal calls */
int rtpopensockets(struct session *, struct in_addr, int);
struct stream	*rtpnewstream(struct session *, ssrc_t);
int		rtprecv(struct session *);
int		rtpupdate(struct session *, struct stream *, struct rtp *);
void rtpinitseq(struct stream *, seq_t);
int rtpupdateseq(struct session *, struct stream *, seq_t);
void            rtpdestroystream(struct stream *);
int		rtpremovestream(struct session *, struct stream *);
struct stream	*rtpgetstream(struct session *, unsigned int);
int rtpreleasestream(struct session *, struct stream *);
unsigned int rtpmkssrc(struct session *);
void rtphton(struct rtp *);
void rtpntoh(struct rtp *);
int rtpstreamcleanup(struct session *, struct stream *);
void rtpinitseq(struct stream *, unsigned short);
int rtpcheckcollision(struct session *, ssrc_t);
void rtprecvthreadfcn(struct session *);
int rtppostevent(struct session *, int, ssrc_t, void *, int);

/* queue internal */
struct rtpln *rtpqextract(struct rtpqueue *, struct rtpln *);
int _rtpqinsert(struct rtpqueue *, struct rtpln *, bool *);
int _rtpqclear(struct rtpqueue *);

#endif