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

📄 main.c

📁 linux环境下用纯c写的RTP协议的通用开发库
💻 C
字号:
/*------------------------------------------------------------------------- * main.c - main *------------------------------------------------------------------------- */#include <stdio.h>#include <rtp.h>#include <rtcp.h>#include <netinet/in.h>#include <netdb.h>#include <math.h>#include <event.h>#include <syn.h>#include <payload.h>#include <sample.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdlib.h>#include <unistd.h>#include <arpa/inet.h>#include <util.h>#include <frame.h>#include <sys/ioctl.h>#include <sys/stropts.h>#include "main.h"#ifdef SOLARIS#include <sys/audioio.h>#endif /* SOLARIS */#ifdef LINUX#include <linux/soundcard.h>#endif /* LINUX */#define MAX_SOURCES 32/* * Uncomment the line below if building  * with MPEG audio support. *//*#define MPEG*//*----------------------------------------------------------------------- * main - wait for audio and play if possible *----------------------------------------------------------------------- */int main(int argc, char **argv) {    char			buf[4000];  unsigned short	*samp16 = (unsigned short *) buf;  bool			found;  int			audio, port, rv, payloadtype;  int			count, i, encoding = 0, one = 1;  ssrc_t		ssrc = 0, sources[MAX_SOURCES];  struct in_addr	addr;  struct session	*psn;  struct synsession	*pssn;  struct timespec	time;  struct sampparam	parameters;  struct encoding	enc;  mediatime_t		ts;  struct sampreadparam  sreadparam;#ifdef SOLARIS  audio_info_t		audio_info;#endif /* SOLARIS */#ifdef LINUX  int			leeway;#endif /* LINUX */  #ifdef MPEG  struct		frameparam fparameters;#endif /* MPEG */  /*   * Check for correct number of arguments.   */  if (argc != 3) {    fprintf(stderr, "Usage: %s <addr> <port>\n", argv[0]);    exit(0);  }    addr.s_addr = inet_addr(argv[1]);  port = atoi(argv[2]);  printf("Session: %s/%d\n", inet_ntoa(addr), port);  /*    * Open a synchronization layer session.   * Use 2k buffers for RTP packets, 64 buffers in pool.   */  pssn = synopen(addr, port, 2048, 64);  if (pssn == NULL) {    fprintf(stderr, "synopen() returned NULL.\n");    exit(1);  }    /*      * Open audio device.     */  if ((audio = open("/dev/audio", O_WRONLY)) < 0) {    perror("open(\"/dev/audio\") failed");    exit(1);  }    /*   * Get a handle to the RTP layer session.   */  synctl(pssn, SYN_CTL_GETRTPSESSION, (char *) &psn, 0);    while(TRUE) {    printf("Looking for audio stream stream...\n");    while(TRUE) {            /*       * Get list of sources known by RTP layer.       */      count = rtpsources(psn, sources, MAX_SOURCES);      for (found = FALSE, i = 0; i < count; i++) {	ssrc = sources[i];		/* 	 * Get the payload type for source ssrc.	 */	rtpctl(psn, RTP_CTL_STREAM_GETPT, (char *) &payloadtype, 0, ssrc);		/*	 * Look up the encoding represented by payloadtype.	 * Determine if it's a supported encoding.	 */	enc = getencoding(payloadtype);	if (strcmp(enc.en_name, "PCMU") == 0 ||	    strcmp(enc.en_name, "PCMA") == 0 ||#ifdef MPEG	    strcmp(enc.en_name, "MPA") == 0 ||#endif /* MPEG */#ifdef SOLARIS	    strcmp(enc.en_name, "DVI4") == 0 ||#endif /* SOLARIS */	    strcmp(enc.en_name, "L16") == 0) {	  found = TRUE;	  break;	}      }      if (found == TRUE)	break;      /*       * If no supported stream found,       * Wait then try again.       */      sleep(1);    }    printf("Found sender: SSRC = 0x%x Encoding = %s\n", ssrc, enc.en_name);    /*     * Set up audio parameters for sample encodings.     */    if (enc.en_format == ENC_SAMPLE) {#ifdef SOLARIS      if (strcmp(enc.en_name, "PCMU") == 0)	encoding = AUDIO_ENCODING_ULAW;            if (strcmp(enc.en_name, "L16") == 0)	encoding = AUDIO_ENCODING_LINEAR;            if (strcmp(enc.en_name, "PCMA") == 0)	encoding = AUDIO_ENCODING_ALAW;            if (strcmp(enc.en_name, "DVI4") == 0)	encoding = AUDIO_ENCODING_DVI;          /*       * Set up audio device.       */          if (ioctl(audio, AUDIO_GETINFO, &audio_info) < 0) {	perror("ioctl1");	exit(1);      }      audio_info.play.sample_rate = enc.en_clkrt;      audio_info.play.channels = enc.en_channels;      audio_info.play.precision = enc.en_unitsz;      audio_info.play.encoding = encoding;            if (ioctl(audio, AUDIO_SETINFO, &audio_info) < 0) {	perror("ioctl2");	fprintf(stderr, "Perhaps %s is not supported by your system.\n",enc.en_name);	exit(1);      }#endif /* SOLARIS */#ifdef LINUX      if (strcmp(enc.en_name, "PCMU") == 0)	encoding = AFMT_MU_LAW;            if (strcmp(enc.en_name, "L16") == 0)	encoding = AFMT_S16_LE; /* Little Endian signed 16 bit */            if (strcmp(enc.en_name, "PCMA") == 0)	encoding = AFMT_A_LAW;            if (ioctl(audio, SNDCTL_DSP_SAMPLESIZE, &enc.en_unitsz) < 0 ||	  ioctl(audio, SNDCTL_DSP_CHANNELS, &enc.en_channels) < 0 ||	  ioctl(audio, SNDCTL_DSP_SETFMT, &encoding) < 0 ||	  ioctl(audio, SNDCTL_DSP_SPEED, &enc.en_clkrt) < 0) {	perror("ioctl2");	fprintf(stderr, "Perhaps %s is not supported by your system.\n", enc.en_name);	exit(1);      }	#endif /* LINUX */    }#ifdef MPEG    if (strcmp(enc.en_name, "MPA") == 0) {      /*       * MPEG does stereo internally,       * so only 1 channel of interleaved frames.       */      fparameters.fp_channels = 1;             /*       * Set pointers to the upcall functions.       */      fparameters.fp_framealigned = aligned;      fparameters.fp_dataoffset = dataoffset;      fparameters.fp_frameduration = frameduration;      fparameters.fp_framelength = framelength;            /*       * Turn the stream on.       */      synstreamon(pssn, ssrc, SYN_STREAMTYPE_FRAME, enc.en_clkrt, enc.en_clkrt, &fparameters);#ifdef LINUX      /*       * Use more leeway for Linux. Gives better performance.       */      leeway = 160000;      synctl(pssn, SYN_CTL_STREAM_SETLEEWAY, (char *) &leeway, ssrc);#endif /* LINUX */      /*       * Set inactive threshold to minimum.       */      rtpctl(psn, RTP_CTL_STREAM_SETINACTTHR, (char *) &one, 0, ssrc);            /*       * Call plaympeg to read from stream and play audio.       */      while(plaympeg(pssn, ssrc, audio) == ERROR);    }    else #endif /* MPEG */      {	/*	 * Play sample-oriented stream.	 * Set sample-read parameters and turn	 * the stream on.	 */	parameters.sp_samplesz = enc.en_unitsz;	parameters.sp_channels = enc.en_channels;	synstreamon(pssn, ssrc, SYN_STREAMTYPE_SAMPLE, enc.en_clkrt, enc.en_clkrt, &parameters);	/*	 * Set inactive threshold to minimum. 1 cycle.	 */	rtpctl(psn, RTP_CTL_STREAM_SETINACTTHR, (char *) &one, 0, ssrc);#ifdef LINUX	/*	 * Use more leeway.	 */	leeway = 20000;	synctl(pssn, SYN_CTL_STREAM_SETLEEWAY, (char *) &leeway, ssrc);#endif	      while(TRUE) {	rv = synread(pssn, ssrc, &time, &ts, buf, sizeof(buf), &sreadparam);	if (rv < 0) {	  printf("Synread returned %d\n", rv);	  	  /* 	   * Loop to top to get another source.	   */	  break; 	}	#if __BYTE_ORDER == __LITTLE_ENDIAN || defined(_LITTLE_ENDIAN)	/*	 * Convert sample byte ordering if necessary.	 */	if (strcmp(enc.en_name, "L16") == 0)	  for (i = 0; i < rv; i++) 	    samp16[i] = ntohs(samp16[i]);#endif /* LITTLE_ENDIAN */	/*	 * Output audio to audio device.	 */	write(audio, buf, (rv * enc.en_unitsz) / 8);      }    }    /*     * Reset audio device before playing another stream.     */#ifdef SOLARIS    ioctl(audio, I_FLUSH, FLUSHW);#endif#ifdef LINUX    ioctl(audio, SNDCTL_DSP_RESET);#endif  }}

⌨️ 快捷键说明

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