示例#1
0
static void
process_delete(session_t *sp, rtp_event *e)
{
	    if (log_fp != 0)
	    {
		struct timeval  tv, *dead;
		int d_sec = -1, d_usec = -1;

		gettimeofday(&tv, 0);

		dead = (struct timeval *) e->data;
		if (dead != 0)
		{
		    d_sec = (int) dead->tv_sec;
		    d_usec = (int) dead->tv_usec;
		}
		fprintf(log_fp, "%d.%06d %d delete %x %d.%06d\n", (int) tv.tv_sec, (int) tv.tv_usec,
			rtp_get_ssrc_count(sp->rtp_session[0]),
			e->ssrc,
			d_sec, d_usec);
		fflush(log_fp);
	    }
        if (e->ssrc != rtp_my_ssrc(sp->rtp_session[0]) && sp->mbus_engine != NULL) {
                struct s_source *s;
                pdb_entry_t     *pdbe;
                if ((s = source_get_by_ssrc(sp->active_sources, e->ssrc)) != NULL) {
                        source_remove(sp->active_sources, s);
                }
                if (pdb_item_get(sp->pdb, e->ssrc, &pdbe)) {
                        pdb_item_destroy(sp->pdb, e->ssrc);
                        /* Will not be in ui if not in pdb */
                        ui_send_rtp_remove(sp, sp->mbus_ui_addr, e->ssrc);
                }
        }
}
示例#2
0
rtcp_app* rtcp_app_site_callback(struct rtp *session, 
				 uint32_t rtp_ts, 
				 int max_size)
{
        struct s_session *sp;
	int len;
	int datalen;
	int slen;

	sp = get_session(session);
	if (sp == NULL) {
	        /* Shouldn't happen */
   	        return NULL;
        }

	if (sp->rtp_session_app_site == NULL) {
	        /* Site identifier not set */
	        return NULL;
	}

	if (sp->rtcp_app_packet_ts == rtp_ts) {
	        /* Already sent an APP for this timestamp */
	        return NULL;
	}

	slen = strlen(sp->rtp_session_app_site);
	datalen = slen;
	if (slen % 4 > 0) {
	        datalen += 4 - (slen % 4);
        }
        len = datalen + sizeof(rtcp_app) - 1;
	if (len > max_size) {
	        /* Can't fit the site id in the current RTCP compound packet */
	        return NULL;
	}

        if (sp->rtcp_app_packet != NULL) {
	  xfree(sp->rtcp_app_packet);
        }

	sp->rtcp_app_packet = xmalloc(len);

	sp->rtcp_app_packet->version = RTP_VERSION;
	sp->rtcp_app_packet->p = 0;
	sp->rtcp_app_packet->subtype = 0;
	sp->rtcp_app_packet->pt = 204;

	/* Host -> Network order is handled by common lib */
	sp->rtcp_app_packet->length = 2 + datalen/4;
	sp->rtcp_app_packet->ssrc = rtp_my_ssrc(session);

	strncpy(sp->rtcp_app_packet->name, "site", 4);
	memset(sp->rtcp_app_packet->data, 0, datalen);
	strncpy(sp->rtcp_app_packet->data, sp->rtp_session_app_site, slen);

	sp->rtcp_app_packet_ts = rtp_ts;
	return sp->rtcp_app_packet;
}
示例#3
0
文件: settings.c 项目: JensenSung/rat
void settings_load_late(session_t *sp)
{
	/* FIXME: This needs to be updated for the transcoder */
        uint32_t my_ssrc;
        struct   utsname u;
        char     hostfmt[] = "RAT v" RAT_VERSION " %s %s (%s)";
        char    *field, username[32] = "";
	load_init();		/* Initial settings come from the common prefs file... */

        /*
         * We check to see it SDES items are set first.  If they are
         * then presumeably it has come from the command line and
         * so it should override saved settings.
         */
        my_ssrc = rtp_my_ssrc(sp->rtp_session[0]);

        if (settings_username(username, sizeof(username) - 1) == FALSE) {
                sprintf(username, "Unknown");
        }

	field = setting_load_str("rtpName", username);
        if (rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NAME) == NULL) {
                debug_msg("username %s %s\n", field, username);
                rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NAME,  field, strlen(field));
        }

	field = setting_load_str("rtpEmail", "");
        if (rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_EMAIL) == NULL) {
                rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_EMAIL, field, strlen(field));
        }
	field = setting_load_str("rtpPhone", "");
        if (rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_PHONE) == NULL) {
                rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_PHONE, field, strlen(field));
        }
	field = setting_load_str("rtpLoc", "");
        if (rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_LOC) == NULL) {
                rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_LOC,   field, strlen(field));
        }
	field = setting_load_str("rtpNote", "");
        if (rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NOTE) == NULL) {
                rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NOTE,   field, strlen(field));
        }

        field = (char*)xmalloc(3 * 256 + sizeof(hostfmt));
        uname(&u);
        sprintf(field, hostfmt, u.sysname, u.release, u.machine);
	rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_TOOL,  field, strlen(field));
        xfree(field);

	/* This is evil [csp] */
	field = xstrdup(" rattest");
	field[0] = 3;
	rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_PRIV,  field, strlen(field));
        xfree(field);

        init_part_two();	/* Switch to pulling settings from the RAT specific prefs file... */
	load_done();
}
示例#4
0
static void
process_rr(session_t *sp, rtp_event *rtp_e)
{
        pdb_entry_t  	*e;
        uint32_t 	 fract_lost, my_ssrc;
	uint32_t	 ssrc = rtp_e->ssrc;
	rtcp_rr		*r = (rtcp_rr *) rtp_e->data;

        /* Calculate rtt estimate */
        my_ssrc =  rtp_my_ssrc(sp->rtp_session[0]);
        if (pdb_item_get(sp->pdb, r->ssrc, &e) == FALSE) {
                /* Maybe deleted or not heard from yet */
                debug_msg("Receiver report on unknown participant (0x%lx)\n", r->ssrc);
                return;
        }

        if (pdb_item_get(sp->pdb, ssrc, &e) &&
            r->ssrc == my_ssrc &&
            r->ssrc != ssrc    && /* filter self reports */
            r->lsr != 0) {
                uint32_t ntp_sec, ntp_frac, ntp32;
                double rtt;
                ntp64_time(&ntp_sec, &ntp_frac);
                ntp32 = ntp64_to_ntp32(ntp_sec, ntp_frac);

                rtt = rtp_rtt_calc(ntp32, r->lsr, r->dlsr);
                /*
                 * Filter out blatantly wrong rtt values.  Some tools might not
                 * implement dlsr and lsr (broken) or forget to do byte-swapping
                 */
                if (rtt < 100.0) {
                        e->last_rtt = rtt;
                        debug_msg("rtt %f\n", rtt);
                } else {
                        debug_msg("Junk rtt (%f secs) ntp32 0x%08x lsr 0x%08x dlsr 0x%08x ?\n", rtt, ntp32, r->lsr, r->dlsr);
                }
                if (e->avg_rtt == 0.0) {
                        e->avg_rtt = e->last_rtt;
                } else {
                        e->avg_rtt += (e->last_rtt - e->avg_rtt) / 2.0;
                }
                if (sp->mbus_engine != NULL) {
                        ui_send_rtp_rtt(sp, sp->mbus_ui_addr, ssrc, e->avg_rtt);
                }
        }
	fract_lost = (r->fract_lost * 100) >> 8;

        /* Update loss stats */
        if (sp->mbus_engine != NULL) {
                ui_send_rtp_packet_loss(sp, sp->mbus_ui_addr, ssrc, r->ssrc, fract_lost);
        }

	/* Do we have to log anything? */
	if ((r->ssrc == my_ssrc) && (sp->logger != NULL)) {
		rtpdump_header(sp->logger, "rtt       ", rtp_e);
		fprintf(sp->logger, "%f\n", e->avg_rtt);
	}
}
示例#5
0
void
ui_send_stats(session_t *sp, char *addr, uint32_t ssrc)
{
	/* Send RAT specific statistics to the user interface... */
        const rtcp_rr           *rr;
        uint32_t                  fract_lost, my_ssrc, total_lost;
        double                   skew_rate;
	char			*args, *mbes;
        struct s_source      	*src;
        uint32_t               	 buffered, delay;
        pdb_entry_t             *pdbe;

	session_validate(sp);
	if (!sp->ui_on) return;
        if (pdb_item_get(sp->pdb, ssrc, &pdbe) == FALSE) {
                debug_msg("pdb entry does not exist (0x%08x)\n", ssrc);
                return;
        }
        pdbe->last_ui_update = sp->cur_ts;

        if (pdbe->enc_fmt) {
		mbes = mbus_encode_str(pdbe->enc_fmt);
                args = (char *) xmalloc(strlen(mbes) + 12);
                sprintf(args, "\"%08x\" %s", pdbe->ssrc, mbes);
                xfree(mbes);
        } else {
                args = (char *) xmalloc(19);
                sprintf(args, "\"%08x\" unknown", pdbe->ssrc);
        }

        mbus_qmsg(sp->mbus_engine, addr, "rtp.source.codec", args, FALSE);
        xfree(args);

        src = source_get_by_ssrc(sp->active_sources, pdbe->ssrc);
        if (src) {
                buffered = timestamp_to_ms(source_get_audio_buffered(src));
                delay    = timestamp_to_ms(source_get_playout_delay(src));
                skew_rate = source_get_skew_rate(src);
        } else {
                buffered  = 0;
                delay     = 0;
                skew_rate = 1.0;
        }

        mbus_qmsgf(sp->mbus_engine, addr, FALSE, "tool.rat.audio.buffered", "\"%08lx\" %ld", (unsigned long)pdbe->ssrc, buffered);
        mbus_qmsgf(sp->mbus_engine, addr, FALSE, "tool.rat.audio.delay", "\"%08lx\" %ld", (unsigned long)pdbe->ssrc, delay);
        mbus_qmsgf(sp->mbus_engine, addr, FALSE, "tool.rat.audio.skew", "\"%08lx\" %.5f", (unsigned long)pdbe->ssrc, skew_rate);
        mbus_qmsgf(sp->mbus_engine, addr, FALSE, "tool.rat.spike.events", "\"%08lx\" %ld", (unsigned long)pdbe->ssrc, pdbe->spike_events);
        mbus_qmsgf(sp->mbus_engine, addr, FALSE, "tool.rat.spike.toged", "\"%08lx\" %ld",  (unsigned long)pdbe->ssrc, pdbe->spike_toged);
        my_ssrc = rtp_my_ssrc(sp->rtp_session[0]);
        rr = rtp_get_rr(sp->rtp_session[0], my_ssrc, pdbe->ssrc);
        if (rr != NULL) {
                fract_lost = (rr->fract_lost * 100) >> 8;
                total_lost = rr->total_lost;
        } else {
示例#6
0
static void process_rr(struct rtp *session, rtp_event * e)
{
        float fract_lost, tmp;
        uint32_t ntp_sec, ntp_frac, now;
        rtcp_rr *r = (rtcp_rr *) e->data;

        if (e->ssrc == rtp_my_ssrc(session)) {
                /* Filter out loopback reports */
                return;
        }

        if (r->ssrc == rtp_my_ssrc(session)) {
                /* Received a reception quality report for data we are sending.  */
                /*                                                               */
                /* Check for excessive congestion: exit if it occurs, to protect */
                /* other users of the network.                                   */
                fract_lost = (r->fract_lost * 100.0) / 256.0;   /* percentage lost packets */
                if (fract_lost > 20) {
                        printf("Receiver 0x%08x reports excessive congestion\n",
                               e->ssrc);
                }

                /* Compute network round-trip time:                              */
                if (r->lsr != 0) {
                        ntp64_time(&ntp_sec, &ntp_frac);
                        now = ntp64_to_ntp32(ntp_sec, ntp_frac);

                        if ((now < r->lsr) || (now - r->lsr < r->dlsr)) {
                                /* Packet arrived before it was sent, ignore. This represents */
                                /* a bug in the remote: either our timestamp was incorrectly  */
                                /* echoed back to us, or the remote miscalculated in time for */
                                /* which it held the packet.                                  */
                                debug_msg("Bogus RTT from 0x%08x ignored\n",
                                          e->ssrc);
                        } else {
                                tmp = ((float)(now - r->lsr - r->dlsr)) / 65536.0;      /* RTT in seconds */
                                RTT = tmp * 1000000;    /* RTT in usec */
                        }
                        debug_msg("  RTT=%d usec\n", RTT);
                }
        }
}
示例#7
0
static void
process_rtp_data(session_t *sp, uint32_t ssrc, rtp_packet *p)
{
        struct s_source *s;
        pdb_entry_t     *e;

        if (sp->filter_loopback && ssrc == rtp_my_ssrc(sp->rtp_session[0])) {
                /* This packet is from us and we are filtering our own       */
                /* packets.                                                  */
                xfree(p);
                return;
        }

        if (pdb_item_get(sp->pdb, ssrc, &e) == FALSE) {
                debug_msg("Packet discarded: unknown source (0x%08x).\n", ssrc);
                xfree(p);
                return;
        }
        e->received++;

        s = source_get_by_ssrc(sp->active_sources, ssrc);
        if (s == NULL) {
                s = source_create(sp->active_sources, ssrc, sp->pdb);
                ui_send_rtp_active(sp, sp->mbus_ui_addr, ssrc);
                debug_msg("Source created\n");
        }

	/* Calculate the relative playout delay, for this source. Needed for lip-sync. */

	/* Discard packet if output is muted... no point wasting time decoding it... */
        if ((sp->playing_audio == FALSE) || (e->mute)) {
                xfree(p);
                return;
        }

	/* Discard packets that contain no data */
	if (p->meta.data_len == 0) {
		printf("Zero length packet\n");
		xfree(p);
		return;
	}

	/* Remove any padding */
        if (p->fields.p) {
                p->meta.data_len -= p->meta.data[p->meta.data_len - 1];
                p->fields.p = 0;
	}
        source_add_packet(s, p);
}
示例#8
0
rtp_session_t * init_rtp_session(uint32_t port, char *addr){
    rtp_session_t *rtp;
    char *mcast_if = NULL;
    double rtcp_bw = DEFAULT_RTCP_BW;
    int ttl = DEFAULT_TTL;
    struct module tmod;
    struct tx *tx_session;

    rtp = (rtp_session_t *) malloc(sizeof(rtp_session_t));
    if (rtp == NULL){
        error_msg("rtp_session: malloc error");
        return NULL;
    }

    rtp->port = port;
    rtp->addr = addr;

    module_init_default(&tmod);

    struct rtp *rtp_conn  = rtp_init_if(addr, mcast_if,
            0, port, ttl,
            rtcp_bw, 0, dummy_callback,
            (void *)NULL, 0);
    if (rtp_conn == NULL){
        error_msg("rtp_session: rtp_init error");
        return NULL;
    }

    rtp_set_option(rtp_conn, RTP_OPT_WEAK_VALIDATION, 1);
    rtp_set_sdes(rtp_conn, rtp_my_ssrc(rtp_conn), RTCP_SDES_TOOL, PACKAGE_STRING, strlen(PACKAGE_STRING));
    rtp_set_send_buf(rtp_conn, DEFAULT_SEND_BUFFER_SIZE);

    tx_session = tx_init_h264(&tmod, MTU, TX_MEDIA_VIDEO, NULL, NULL);
    if (tx_session == NULL){
        error_msg("rtp_session: tx_init error");
        return NULL;
    }

    rtp->rtp = rtp_conn;
    rtp->tx_session = tx_session;

    return rtp;
}
示例#9
0
/*
 * recv_callback - callback for when bytestream is active - basically, 
 * put things on the queue
 */
int CRtpByteStreamBase::recv_callback (struct rtp *session, rtp_event *e)
{
  switch (e->type) {
  case RX_RTP:
    rtp_packet *rpak;
    rpak = (rtp_packet *)e->data;
    if (rpak->rtp_data_len == 0) {
      xfree(rpak);
    } else {
      // need to add lock/unlock of mutex here
      if (m_have_recv_last_ts) {
	int32_t diff = rpak->rtp_pak_ts - m_recv_last_ts;
	int32_t ts, nts;
	ts = m_timescale * 2;
	nts = 0 - ts;
	if (diff > ts || diff < nts) {
	  rtp_message(LOG_INFO, "%s - rtp timestamp diff %d last %u now %u", 
		      m_name, diff, m_recv_last_ts, rpak->rtp_pak_ts);
	  flush_rtp_packets();
	  reset();
	}
		      
      }
      m_have_recv_last_ts = true;
      m_recv_last_ts = rpak->rtp_pak_ts;
      if (m_buffering == 0) {
	rpak->pd.rtp_pd_timestamp = get_time_of_day();
	rpak->pd.rtp_pd_have_timestamp = 1;
      }
      if (SDL_mutexP(m_rtp_packet_mutex) == -1) {
	rtp_message(LOG_CRIT, "SDL Lock mutex failure in rtp bytestream recv");
	break;
      }
      add_rtp_packet_to_queue(rpak, &m_head, &m_tail, m_name);
      if (SDL_mutexV(m_rtp_packet_mutex) == -1) {
	rtp_message(LOG_CRIT, "SDL Lock mutex failure in rtp bytestream recv");
	break;
      }
      m_recvd_pak = true;
      check_buffering();
    }
    break;
  case RX_SR:
    rtcp_sr *srpak;
    srpak = (rtcp_sr *)e->data;
    if (rtp_my_ssrc(session) != e->ssrc) {
      //rtp_message(LOG_DEBUG, "%s received rtcp", m_name);
      calculate_wallclock_offset_from_rtcp(srpak->ntp_frac, 
					   srpak->ntp_sec, 
					   srpak->rtp_ts);
    }
    break;
  case RX_APP:
    free(e->data);
    break;
  default:
#if 0
    rtp_message(LOG_DEBUG, "Thread %u - Callback from rtp with %d %p", 
		SDL_ThreadID(),e->type, e->rtp_data);
#endif
    break;
  }
  return m_buffering;
}
示例#10
0
int
os_sound_start (call_t * ca, int port)
{
  int p, cond;
  int bits = 16;
  int stereo = 0;               /* 0 is mono */
  int rate = 8000;
  int blocksize = 512;

  if (ca->local_sendrecv == _SENDRECV || ca->local_sendrecv == _RECVONLY)
    {
      ca->fd = open (AUDIO_DEVICE, O_RDWR | O_NONBLOCK);
      if (ca->fd < 0)
        return -EWOULDBLOCK;
      fcntl (ca->fd, F_SETFL, fcntl (ca->fd, F_GETFL) & ~O_NONBLOCK);

      ioctl (ca->fd, SNDCTL_DSP_RESET, 0);

      p = bits;                 /* 16 bits */
      ioctl (ca->fd, SNDCTL_DSP_SAMPLESIZE, &p);

      p = stereo;               /* number of channels */
      ioctl (ca->fd, SNDCTL_DSP_CHANNELS, &p);

#ifdef USE_PCM
      p = AFMT_S16_NE;          /* choose LE or BE (endian) */
      ioctl (ca->fd, SNDCTL_DSP_SETFMT, &p);
#else
      if (ca->payload == 0)
        p = AFMT_MU_LAW;
      else if (ca->payload == 8)
        p = AFMT_A_LAW;
      else if (ca->payload == 110 || ca->payload == 111)
        p = AFMT_S16_NE;        /* choose LE or BE (endian) */
      ioctl (ca->fd, SNDCTL_DSP_SETFMT, &p);
#endif

      p = rate;                 /* rate in khz */
      ioctl (ca->fd, SNDCTL_DSP_SPEED, &p);

      ioctl (ca->fd, SNDCTL_DSP_GETBLKSIZE, &min_size);
      if (min_size > blocksize)
        {
          cond = 1;
          p = min_size / blocksize;
          while (cond)
            {
              int i = ioctl (ca->fd, SNDCTL_DSP_SUBDIVIDE, &p);

              /* fprintf(stderr, "SUB_DIVIDE said error=%i,errno=%i\n",i,errno); */
              if ((i == 0) || (p == 1))
                cond = 0;
              else
                p = p / 2;
            }
        }
      ioctl (ca->fd, SNDCTL_DSP_GETBLKSIZE, &min_size);
      if (min_size > blocksize)
        {
          fprintf (stderr, "dsp block size set to %i.", min_size);
          exit (0);
      } else
        {
          /* no need to access the card with less latency than needed */
          min_size = blocksize;
        }

      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_INFO2, NULL,
                   "blocksize = %i\n", min_size));
  } else
    {
      /* send a wav file! */
      ca->fd = open (ca->wav_file, O_RDONLY);
      if (ca->fd < 0)
        {
          OSIP_TRACE (osip_trace
                      (__FILE__, __LINE__, OSIP_INFO2, NULL,
                       "Could not open wav file: %s\n", ca->wav_file));
          return -1;
        }
    }


#ifdef SPEEX_SUPPORT
  {
    float vbr_qual;
    int value;
    int quality;

    ca->speex_enc = speex_encoder_init (&speex_nb_mode);        /* 8kHz */
    /* 16kHz speex_enc = speex_encoder_init(&speex_wb_mode);   */
    /* 32kHz speex_enc = speex_encoder_init(&speex_uwb_mode);  */
    ca->speex_dec = speex_decoder_init (&speex_nb_mode);
    value = 1;
    speex_decoder_ctl (ca->speex_dec, SPEEX_SET_ENH, &value);
    quality = 8;                /* 15kb */
    speex_encoder_ctl (ca->speex_enc, SPEEX_SET_QUALITY, &quality);
    /* ou bien le bit rate:
       value = 15000; // 15kb
       speex_encoder_ctl(ca->speex_enc, SPEEX_SET_BITRATE, &value);
     */
    /* silence suppression (VAD)
       value = 1; // 15kb
       speex_encoder_ctl(ca->speex_enc, SPEEX_SET_VAD, &value);
       Discontinuous transmission (DTX)
       value = 1; // 15kb
       speex_encoder_ctl(ca->speex_enc, SPEEX_SET_DTX, &value);

       Variable Bit Rate (VBR)
       value = 1; // 15kb
       speex_encoder_ctl(ca->speex_enc, SPEEX_SET_VBR, &value);
       vbr_qual = 5,0; // between 0 and 10
       speex_encoder_ctl(ca->speex_enc, SPEEX_SET_VBR_QUALITY, &vbr_qual);

       Average bit rate: (ABR)
       value = 15000; // 15kb
       speex_encoder_ctl(ca->speex_enc, SPEEX_SET_ABR, &value);
     */
    speex_encoder_ctl (ca->speex_enc, SPEEX_GET_FRAME_SIZE, &ca->speex_fsize);

    ca->speex_nb_packet = 1;
    speex_bits_init (&(ca->speex_bits));
    speex_bits_init (&(ca->dec_speex_bits));
  }
#endif

  if (ca->local_sendrecv == _SENDRECV)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_INFO2, NULL,
                   "starting sendrecv session\n"));
  } else if (ca->local_sendrecv == _SENDONLY)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_INFO2, NULL,
                   "starting sendonly session\n"));
  } else
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_INFO2, NULL,
                   "starting recvonly session\n"));
    }

  ca->rtp_session = rtp_init (ca->remote_sdp_audio_ip,
                              port,
                              ca->remote_sdp_audio_port,
                              16, 64000, rtp_event_handler, (void *) ca);

  if (ca->rtp_session)
    {
      const char *username = "******";    /* should be taken from the SDP */
      const char *telephone = "0033-MY-NUMBER";
      const char *app_name = "josua";
      uint32_t my_ssrc = rtp_my_ssrc (ca->rtp_session);

      /* set local participant info */
      rtp_set_sdes (ca->rtp_session, my_ssrc, RTCP_SDES_NAME,
                    username, strlen (username));
      rtp_set_sdes (ca->rtp_session, my_ssrc, RTCP_SDES_PHONE,
                    telephone, strlen (telephone));
      rtp_set_sdes (ca->rtp_session, my_ssrc, RTCP_SDES_TOOL,
                    app_name, strlen (app_name));

      /* Filter out local packets if requested */
      /* rtp_set_option(ca->rtp_session, RTP_OPT_FILTER_MY_PACKETS, filter_me); */
      rtp_set_option (ca->rtp_session, RTP_OPT_WEAK_VALIDATION, TRUE);

      ca->enable_audio = 1;
      ca->audio_thread = osip_thread_create (20000, os_sound_start_thread, ca);
  } else
    {
      fprintf (stderr, "Could not initialize session for %s port %d\n",
               ca->remote_sdp_audio_ip, ca->remote_sdp_audio_port);
    }

  return 0;
}
示例#11
0
void *
os_sound_start_thread (void *_ca)
{
  int i;
  call_t *ca = (call_t *) _ca;
  struct timeval timeout;
  uint32_t rtp_ts, round;
  uint8_t mulaw_buffer[MULAW_BYTES * 16];
  int mulaw_buffer_pos;

#ifdef USE_PCM
  char data_out[MULAW_BYTES * 2 * 16];
#endif

  fprintf (stderr, "Sending and listening to ");
  fprintf (stderr, "%s port %d (local SSRC = 0x%08x)\n",
           rtp_get_addr (ca->rtp_session),
           rtp_get_rx_port (ca->rtp_session), rtp_my_ssrc (ca->rtp_session));

  round = 0;
  mulaw_buffer_pos = 0;

  while (ca->enable_audio != -1)
    {
      struct timeval t_beg;
      struct timeval t_end;
      struct timeval interval;

      gettimeofday (&t_beg, NULL);

      round++;
      /* original line rtp_ts = round * MULAW_MS; */
      rtp_ts = round * MULAW_BYTES;

      if (ca->local_sendrecv != _RECVONLY)
        {
          if (mulaw_buffer_pos < MULAW_BYTES * 4)
            {
              /* Send control packets */
              rtp_send_ctrl (ca->rtp_session, rtp_ts, NULL);

              /* Send data packets */
#ifdef USE_PCM
              i = read (ca->fd, data_out, MULAW_BYTES * 4);
              if (ca->local_sendrecv == _SENDRECV
                  || ca->local_sendrecv == _RECVONLY)
                {
              } else
                {
                  if (i < MULAW_BYTES * 4)
                    {
                      memset (data_out, 0, MULAW_BYTES * 4);
                      OSIP_TRACE (osip_trace
                                  (__FILE__, __LINE__, OSIP_INFO2, NULL,
                                   "restarting: %i\n", i));
                      close (ca->fd);
                      /* send a wav file! */
                      ca->fd = open (ca->wav_file, O_RDONLY);
                      if (ca->fd < 0)
                        {
                          OSIP_TRACE (osip_trace
                                      (__FILE__, __LINE__, OSIP_INFO2, NULL,
                                       "Could not open wav file: %s\n",
                                       ca->wav_file));
                          ca->fd = -1;
                          break;
                        }
                      i = read (ca->fd, data_out, MULAW_BYTES * 4);
                    }
                }
              if (ca->payload == 8)     /* A-Law */
                alaw_enc (data_out, mulaw_buffer + mulaw_buffer_pos, i);
              if (ca->payload == 0)     /* Mu-Law */
                mulaw_enc (data_out, mulaw_buffer + mulaw_buffer_pos, i);
              i = i / 2;
              mulaw_buffer_pos = mulaw_buffer_pos + i;
#else
              memset (mulaw_buffer + mulaw_buffer_pos, 0, MULAW_BYTES * 2);
              i = read (ca->fd, mulaw_buffer + mulaw_buffer_pos, MULAW_BYTES * 2);      /* ?? */
              mulaw_buffer_pos = mulaw_buffer_pos + i;
#endif
            }

          i = 0;
          if (mulaw_buffer_pos >= MULAW_BYTES)
            {
              i = rtp_send_data (ca->rtp_session, rtp_ts, ca->payload,
                                 0, 0, 0, (char *) mulaw_buffer, MULAW_BYTES,
                                 0, 0, 0);
              memmove (mulaw_buffer, mulaw_buffer + MULAW_BYTES, MULAW_BYTES * 15);
              mulaw_buffer_pos = mulaw_buffer_pos - MULAW_BYTES;
            }
      } else
        {
          /* Send control packets */
          rtp_send_ctrl (ca->rtp_session, rtp_ts, NULL);
        }

      /* Receive control and data packets */
      timeout.tv_sec = 0;
      timeout.tv_usec = 0;
      i = rtp_recv (ca->rtp_session, &timeout, rtp_ts);
      /* State maintenance */
      rtp_update (ca->rtp_session);

      gettimeofday (&t_end, NULL);

      /* make a diff between t_beg and t_end */
      interval.tv_sec = t_end.tv_sec - t_beg.tv_sec;
      interval.tv_usec = t_end.tv_usec - t_beg.tv_usec;

      if (interval.tv_usec < 0)
        {
          interval.tv_usec += 1000000L;
          --interval.tv_sec;
        }
      interval.tv_usec = (MULAW_MS * 1000 - interval.tv_usec);
      if (interval.tv_usec < 0)
        {
          interval.tv_usec += 1000000L;
          --interval.tv_sec;
        }
      if (interval.tv_sec < 0)
        {
          interval.tv_sec = 0;
          interval.tv_usec = 0;
        }
      select (0, NULL, NULL, NULL, &interval);
    }
  return NULL;
}
示例#12
0
文件: settings.c 项目: JensenSung/rat
void settings_save(session_t *sp)
{
	/* FIXME: This needs to be updated for the transcoder */
        const codec_format_t 		*pri_cf;
        const audio_port_details_t      *iapd      = NULL;
        const audio_port_details_t      *oapd      = NULL;
        const audio_format 		*af        = NULL;
        const repair_details_t          *repair    = NULL;
        const converter_details_t       *converter = NULL;
	const audio_device_details_t    *add       = NULL;
        const cc_details_t 		*ccd       = NULL;
	codec_id_t	 		 pri_id;

	int				 cc_len;
	char				*cc_param;
	int		 		 i;
        uint16_t                          j,n;
        uint32_t                          my_ssrc;

	pri_id   = codec_get_by_payload(sp->encodings[0]);
        pri_cf   = codec_get_format(pri_id);
        cc_len   = 3 * (CODEC_LONG_NAME_LEN + 4) + 1;
        cc_param = (char*) xmalloc(cc_len);
        channel_encoder_get_parameters(sp->channel_coder, cc_param, cc_len);
        ccd = channel_get_coder_identity(sp->channel_coder);

        n = (uint16_t)converter_get_count();
        for (j = 0; j < n; j++) {
                converter = converter_get_details(j);
                if (sp->converter == converter->id) {
			break;
                }
        }

        n = repair_get_count();
        for (j = 0; j < n; j++) {
                repair = repair_get_details(j);
                if (sp->repair == repair->id) {
                        break;
                }
        }

        n = (int)audio_get_device_count();
        for (i = 0; i < n; i++) {
                add = audio_get_device_details(i);
                if (sp->audio_device == add->descriptor) {
                        break;
                }
        }

        af = audio_get_ifmt(sp->audio_device);

        for(i = 0; i < audio_get_iport_count(sp->audio_device); i++) {
                iapd = audio_get_iport_details(sp->audio_device, i);
                if (iapd->port == audio_get_iport(sp->audio_device)) {
                        break;
                }
        }

        for(i = 0; i < audio_get_oport_count(sp->audio_device); i++) {
                oapd = audio_get_oport_details(sp->audio_device, i);
                if (oapd->port == audio_get_oport(sp->audio_device)) {
                        break;
                }
        }

	save_init_rtp();
        my_ssrc = rtp_my_ssrc(sp->rtp_session[0]);
        setting_save_str("rtpName",  rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NAME));
        setting_save_str("rtpEmail", rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_EMAIL));
        setting_save_str("rtpPhone", rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_PHONE));
        setting_save_str("rtpLoc",   rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_LOC));
        setting_save_str("rtpNote",  rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NOTE));
        save_done_rtp();

        save_init_rat();
        setting_save_str("audioTool", rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_TOOL));
	setting_save_str("audioDevice",     add->name);
	setting_save_int("audioFrequency",  af->sample_rate);
	setting_save_int("audioChannelsIn", af->channels);

	/* If we save a dynamically mapped codec we crash when we reload on startup */
	if (pri_cf->default_pt != CODEC_PAYLOAD_DYNAMIC) {
                setting_save_str("audioPrimary", pri_cf->short_name);
	}

	setting_save_int("audioUnits", channel_encoder_get_units_per_packet(sp->channel_coder));
	/* Don't save the layered channel coder - you need to start it */
	/* from the command line anyway                                */
	if (strcmp(ccd->name, "Layering") == 0) {
		setting_save_str("audioChannelCoding", "Vanilla");
	} else {
                setting_save_str("audioChannelCoding", ccd->name);
        }
        setting_save_str("audioChannelParameters", cc_param);
	setting_save_str("audioRepair",            repair->name);
	setting_save_str("audioAutoConvert",       converter->name);
	setting_save_int("audioLimitPlayout",      sp->limit_playout);
	setting_save_int("audioMinPlayout",        sp->min_playout);
	setting_save_int("audioMaxPlayout",        sp->max_playout);
	setting_save_int("audioLecture",           sp->lecture);
	setting_save_int("audio3dRendering",       sp->render_3d);
	setting_save_int("audioAGC",               sp->agc_on);
	setting_save_int("audioLoopback",          sp->loopback_gain);
	setting_save_int("audioEchoSuppress",      sp->echo_suppress);
	setting_save_int("audioOutputGain",        audio_get_ogain(sp->audio_device));
	setting_save_int("audioInputGain",         audio_get_igain(sp->audio_device));
	setting_save_str("audioOutputPort",        oapd->name);
	setting_save_str("audioInputPort",         iapd->name);
	setting_save_int("audioPowermeters",       sp->meter);

	setting_save_str("audioSilence",  sd_name(sp->silence_detection));
        setting_save_int("audioSilenceManualThresh", sp->manual_sd_thresh);

	/* We do not save audioOutputMute and audioInputMute by default, but should */
	/* recognize them when reloading.                                           */
	save_done_rat();
        xfree(cc_param);
}