Пример #1
0
static int get_receiver_output_fmt(MSFilter *f, void *arg) {
	ReceiverData *d = (ReceiverData *) f->data;
	MSPinFormat *pinFmt = (MSPinFormat *)arg;
	PayloadType *pt = rtp_profile_get_payload(rtp_session_get_profile(d->session), rtp_session_get_send_payload_type(d->session));
	pinFmt->fmt = ms_factory_get_audio_format(f->factory, pt->mime_type, pt->clock_rate, pt->channels, NULL);
	return 0;
}
Пример #2
0
static int sender_set_session(MSFilter * f, void *arg)
{
	SenderData *d = (SenderData *) f->data;
	RtpSession *s = (RtpSession *) arg;
	PayloadType *pt =
		rtp_profile_get_payload(rtp_session_get_profile(s),
								rtp_session_get_send_payload_type(s));
	if (pt != NULL) {
		d->rate = pt->clock_rate;
	} else {
		ms_warning("Sending undefined payload type ?");
	}
	d->session = s;
	return 0;
}
Пример #3
0
static int sender_set_session(MSFilter * f, void *arg)
{
	SenderData *d = (SenderData *) f->data;
	RtpSession *s = (RtpSession *) arg;
	PayloadType *pt =
		rtp_profile_get_payload(rtp_session_get_profile(s),
								rtp_session_get_send_payload_type(s));
	if (pt != NULL) {
		d->rate = pt->clock_rate;
		d->dtmf_duration=(default_dtmf_duration_ms*d->rate)/1000;
		d->dtmf_ts_step=(20*d->rate)/1000;
		send_stun_packet(s);
	} else {
		ms_warning("Sending undefined payload type ?");
	}
	d->session = s;
	return 0;
}
Пример #4
0
/**
 *	Allocates a new rtp packet to be used to add named telephony events. The application can use
 *	then rtp_session_add_telephone_event() to add named events to the packet.
 *	Finally the packet has to be sent with rtp_session_sendm_with_ts().
 *
 * @param session a rtp session.
 * @param start boolean to indicate if the marker bit should be set.
 *
 * @return a message block containing the rtp packet if successfull, NULL if the rtp session
 * cannot support telephony event (because the rtp profile it is bound to does not include
 * a telephony event payload type).
**/
mblk_t	*rtp_session_create_telephone_event_packet(RtpSession *session, int start)
{
	mblk_t *mp;
	rtp_header_t *rtp;
	PayloadType *cur_pt=rtp_profile_get_payload(session->snd.profile, rtp_session_get_send_payload_type(session));
	int tev_pt = session->tev_send_pt;
	
	if (tev_pt != -1){
		PayloadType *cur_tev_pt=rtp_profile_get_payload(session->snd.profile, tev_pt);
		if (!cur_tev_pt){
			ortp_error("Undefined telephone-event payload type %i choosen for sending telephone event", tev_pt);
			tev_pt = -1;
		}else if (cur_pt && cur_tev_pt->clock_rate != cur_pt->clock_rate){
			ortp_warning("Telephone-event payload type %i has clockrate %i while main audio codec has clockrate %i: this is not permitted.",
				tev_pt, cur_tev_pt->clock_rate, cur_pt->clock_rate);
		}
	}
	
	if (tev_pt == -1){
		tev_pt = rtp_profile_find_payload_number(session->snd.profile, "telephone-event", cur_pt ? cur_pt->clock_rate : 8000, 1);
	}
	return_val_if_fail(tev_pt!=-1,NULL);
	
	mp=allocb(RTP_FIXED_HEADER_SIZE+TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED);
	if (mp==NULL) return NULL;
	rtp=(rtp_header_t*)mp->b_rptr;
	rtp->version = 2;
	rtp->markbit=start;
	rtp->padbit = 0;
	rtp->extbit = 0;
	rtp->cc = 0;
	rtp->ssrc = session->snd.ssrc;
	/* timestamp set later, when packet is sended */
	/*seq number set later, when packet is sended */
	
	/*set the payload type */
	rtp->paytype=tev_pt;
	
	/*copy the payload */
	mp->b_wptr+=RTP_FIXED_HEADER_SIZE;
	return mp;
}
Пример #5
0
static bool_t simple_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtcp){
	MSSimpleQosAnalyzer *obj=(MSSimpleQosAnalyzer*)objbase;
	rtpstats_t *cur;
	const report_block_t *rb=NULL;
	bool_t got_stats=FALSE;
	
	if (rtcp_is_SR(rtcp)){
		rb=rtcp_SR_get_report_block(rtcp,0);
	}else if (rtcp_is_RR(rtcp)){
		rb=rtcp_RR_get_report_block(rtcp,0);
	}
	if (rb && report_block_get_ssrc(rb)==rtp_session_get_send_ssrc(obj->session)){

		obj->curindex++;
		cur=&obj->stats[obj->curindex % STATS_HISTORY];

		if (obj->clockrate==0){
			PayloadType *pt=rtp_profile_get_payload(rtp_session_get_send_profile(obj->session),rtp_session_get_send_payload_type(obj->session));
			if (pt!=NULL) obj->clockrate=pt->clock_rate;
			else return FALSE;
		}
		if (ortp_loss_rate_estimator_process_report_block(objbase->lre,&obj->session->rtp,rb)){
			cur->lost_percentage=ortp_loss_rate_estimator_get_value(objbase->lre);
			cur->int_jitter=1000.0*(float)report_block_get_interarrival_jitter(rb)/(float)obj->clockrate;
			cur->rt_prop=rtp_session_get_round_trip_propagation(obj->session);

			ms_message("MSSimpleQosAnalyzer: lost_percentage=%f, int_jitter=%f ms, rt_prop=%f sec",
				cur->lost_percentage,cur->int_jitter,cur->rt_prop);
			got_stats=TRUE;
		}
	}
	return got_stats;
}
Пример #6
0
static bool_t stateful_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtcp){
	MSStatefulQosAnalyzer *obj=(MSStatefulQosAnalyzer*)objbase;
	rtpstats_t *cur;
	const report_block_t *rb=NULL;
	if (rtcp_is_SR(rtcp)){
		rb=rtcp_SR_get_report_block(rtcp,0);
	}else if (rtcp_is_RR(rtcp)){
		rb=rtcp_RR_get_report_block(rtcp,0);
	}
	if (rb && report_block_get_ssrc(rb)==rtp_session_get_send_ssrc(obj->session)){
		double up_bw = stateful_qos_analyzer_upload_bandwidth(obj);
		int total_emitted=stateful_qos_analyzer_get_total_emitted(obj, rb);
		obj->curindex++;
		cur=&obj->stats[obj->curindex % STATS_HISTORY];

		if (obj->clockrate==0){
			PayloadType *pt=rtp_profile_get_payload(rtp_session_get_send_profile(obj->session),rtp_session_get_send_payload_type(obj->session));
			if (pt!=NULL) obj->clockrate=pt->clock_rate;
			else return FALSE;
		}

		cur->lost_percentage=100.0*(float)report_block_get_fraction_lost(rb)/256.0;
		cur->int_jitter=1000.0*(float)report_block_get_interarrival_jitter(rb)/(float)obj->clockrate;
		cur->rt_prop=rtp_session_get_round_trip_propagation(obj->session);
		ms_message("MSSimpleQosAnalyzer: lost_percentage=%f, int_jitter=%f ms, rt_prop=%f sec",cur->lost_percentage,cur->int_jitter,cur->rt_prop);
		if (obj->curindex>2){
			double loss_rate = cur->lost_percentage/100.0;
			int cum_loss=report_block_get_cum_packet_loss(rb);
			int cum_loss_curr=cum_loss - obj->cum_loss_prev;
			int uniq_emitted=report_block_get_high_ext_seq(rb) - obj->previous_ext_high_seq_num_rec;

			if (obj->previous_ext_high_seq_num_rec > 0){
				loss_rate=(1. - (uniq_emitted - cum_loss_curr) * 1.f / total_emitted);
				ms_debug("MSQosStatefulAnalyzer[%p]: RECEIVE estimated loss rate=%f vs 'real'=%f",
					obj, loss_rate, report_block_get_fraction_lost(rb)/256.);
			}

			obj->latest=ms_new0(rtcpstatspoint_t, 1);
			obj->latest->timestamp=ms_time(0);
			obj->latest->bandwidth=up_bw;
			obj->latest->loss_percent=MAX(0,loss_rate);
			obj->latest->rtt=cur->rt_prop;

			obj->rtcpstatspoint=ms_list_insert_sorted(obj->rtcpstatspoint, obj->latest, (MSCompareFunc)sort_points);

			if (obj->latest->loss_percent < 1e-5){
				MSList *it=obj->rtcpstatspoint;
				MSList *latest_pos=ms_list_find(obj->rtcpstatspoint,obj->latest);
				while (it!=latest_pos->next){
					((rtcpstatspoint_t *)it->data)->loss_percent=0.f;
					it = it->next;
				}
			}
			ms_debug("MSQosStatefulAnalyzer[%p]: one more %d: %f %f",
				obj, obj->curindex-2, obj->latest->bandwidth, obj->latest->loss_percent);

			if (ms_list_size(obj->rtcpstatspoint) > ESTIM_HISTORY){
#ifdef DEBUG
				int prev_size = ms_list_size(obj->rtcpstatspoint);
#endif
				/*clean everything which occurred 60 sec or more ago*/
				time_t clear_time = ms_time(0) - 60;
				obj->rtcpstatspoint = ms_list_remove_custom(obj->rtcpstatspoint, (MSCompareFunc)earlier_than, &clear_time);
				ms_debug("MSQosStatefulAnalyzer[%p]: Reached list maximum capacity (count=%d) --> Cleaned list (count=%d)",
					obj, prev_size, ms_list_size(obj->rtcpstatspoint));
			}
		}
		obj->cum_loss_prev=report_block_get_cum_packet_loss(rb);
		obj->previous_ext_high_seq_num_rec=report_block_get_high_ext_seq(rb);
	}
	return rb!=NULL;
}