Example #1
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);
	}
}
Example #2
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);
                }
        }
}
Example #3
0
static void
process_sdes(session_t *sp, uint32_t ssrc, rtcp_sdes_item *d)
{
        pdb_entry_t *e;

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

        if (sp->mbus_engine == NULL) {
                /* Nowhere to send updates to, so ignore them.               */
                return;
        }

        switch(d->type) {
        case RTCP_SDES_END:
                /* This is the end of the SDES list of a packet.  Nothing    */
                /* for us to deal with.                                      */
                break;
        case RTCP_SDES_CNAME:
	    if (log_fp != 0)
	    {
		struct timeval  tv;
		gettimeofday(&tv, 0);

		fprintf(log_fp, "%d.%06d %d cname %x %s\n", (int) tv.tv_sec, (int) tv.tv_usec,
			(int) rtp_get_ssrc_count(sp->rtp_session[0]),
			(int) ssrc,
			rtp_get_sdes(sp->rtp_session[0], ssrc, RTCP_SDES_CNAME));
		fflush(log_fp);
	    }
                ui_send_rtp_cname(sp, sp->mbus_ui_addr, ssrc);
                break;
        case RTCP_SDES_NAME:
                ui_send_rtp_name(sp, sp->mbus_ui_addr, ssrc);
                break;
        case RTCP_SDES_EMAIL:
                ui_send_rtp_email(sp, sp->mbus_ui_addr, ssrc);
                break;
        case RTCP_SDES_PHONE:
                ui_send_rtp_phone(sp, sp->mbus_ui_addr, ssrc);
                break;
        case RTCP_SDES_LOC:
                ui_send_rtp_loc(sp, sp->mbus_ui_addr, ssrc);
                break;
        case RTCP_SDES_TOOL:
                ui_send_rtp_tool(sp, sp->mbus_ui_addr, ssrc);
                break;
        case RTCP_SDES_NOTE:
                ui_send_rtp_note(sp, sp->mbus_ui_addr, ssrc);
                break;
        case RTCP_SDES_PRIV:
		ui_send_rtp_priv(sp, sp->mbus_ui_addr, ssrc);
                break;
        default:
                debug_msg("Ignoring SDES type (0x%02x) from (0x%08x).\n", ssrc);
        }
}
Example #4
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 {
Example #5
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);
}
timestamp_t 
playout_calc(session_t *sp, uint32_t ssrc, timestamp_t transit, int new_spurt)
/*****************************************************************************/
/* The primary purpose of this function is to calculate the playout point    */
/* for new talkspurts (new_spurt).  It also maintains the jitter and transit */
/* time estimates from the source to us.  The value returned is the local    */
/* playout time.                                                             */
/*****************************************************************************/
{
        timestamp_t delta_transit;
        pdb_entry_t *e;

        pdb_item_get(sp->pdb, ssrc, &e);
        assert(e != NULL);

        delta_transit = ts_abs_diff(transit, e->avg_transit);
        if (ts_gt(transit, e->avg_transit)) {
                e->avg_transit = ts_add(e->avg_transit, ts_div(delta_transit,16));
        } else {
                e->avg_transit = ts_sub(e->avg_transit, ts_div(delta_transit,16));
        }

        if (new_spurt == TRUE) {
                timestamp_t hvar, jvar; /* Host and jitter components       */
                debug_msg("New talkspurt\n");
                hvar = playout_constraints_component(sp, e);
                jvar = ts_mul(e->jitter, PLAYOUT_JITTER_SCALE);
                if (ts_gt(hvar, jvar)) {
                        e->playout = hvar;
                } else {
                        e->playout = jvar;
                }
                e->transit = e->avg_transit;
        } else {
                /* delta_transit is abs((s[j+1] - d[j+1]) - (s[j] - d[j]))  */
                delta_transit   = ts_abs_diff(transit, e->last_transit);
                /* Update jitter estimate using                             */
                /*                  jitter = (7/8)jitter + (1/8) new_jitter */
                e->jitter = ts_mul(e->jitter, 7);
                e->jitter = ts_add(e->jitter, delta_transit);     
                e->jitter = ts_div(e->jitter, 8);

        }
        e->last_transit = transit;

        return e->playout;
}
Example #7
0
static void
process_app(session_t *sp, uint32_t ssrc, rtcp_app *app)
{
  if (strncmp(app->name, "site", 4) == 0) {
    int site_id_len = 4*(app->length - 2);
    pdb_entry_t *e;

    if (pdb_item_get(sp->pdb, ssrc, &e) == FALSE) {
      debug_msg("process_app: unknown source (0x%08x).\n", ssrc);
      return;
    } else {
      if (e->siteid == NULL) {
	e->siteid = xmalloc(site_id_len + 1);
	strncpy(e->siteid, app->data, site_id_len);
	e->siteid[site_id_len] = '\0';
      }
	
      ui_send_rtp_app_site(sp, sp->mbus_ui_addr, ssrc, e->siteid);
    }
  }
}