Commit 4b156f31 authored by Simon Morlat's avatar Simon Morlat
Browse files

make use of new OrtpLossRateEstimator

parent c3529c41
...@@ -100,10 +100,10 @@ struct _MSQosAnalyzerDesc{ ...@@ -100,10 +100,10 @@ struct _MSQosAnalyzerDesc{
**/ **/
struct _MSQosAnalyzer{ struct _MSQosAnalyzer{
MSQosAnalyzerDesc *desc; MSQosAnalyzerDesc *desc;
char *label;
void (*on_action_suggested)(void*, const char*,const char*); void (*on_action_suggested)(void*, const char*,const char*);
void *on_action_suggested_user_pointer; void *on_action_suggested_user_pointer;
int refcnt; int refcnt;
enum { enum {
Simple, Simple,
Stateful, Stateful,
...@@ -112,6 +112,7 @@ struct _MSQosAnalyzer{ ...@@ -112,6 +112,7 @@ struct _MSQosAnalyzer{
MSQosAnalyzer * ms_qos_analyzer_ref(MSQosAnalyzer *obj); MSQosAnalyzer * ms_qos_analyzer_ref(MSQosAnalyzer *obj);
void ms_qos_analyzer_unref(MSQosAnalyzer *obj); void ms_qos_analyzer_unref(MSQosAnalyzer *obj);
void ms_qos_analyser_set_label(MSQosAnalyzer *obj, const char *label);
void ms_qos_analyzer_suggest_action(MSQosAnalyzer *obj, MSRateControlAction *action); void ms_qos_analyzer_suggest_action(MSQosAnalyzer *obj, MSRateControlAction *action);
bool_t ms_qos_analyzer_has_improved(MSQosAnalyzer *obj); bool_t ms_qos_analyzer_has_improved(MSQosAnalyzer *obj);
bool_t ms_qos_analyzer_process_rtcp(MSQosAnalyzer *obj, mblk_t *rtcp); bool_t ms_qos_analyzer_process_rtcp(MSQosAnalyzer *obj, mblk_t *rtcp);
......
...@@ -36,6 +36,11 @@ extern "C"{ ...@@ -36,6 +36,11 @@ extern "C"{
**/ **/
MS2_PUBLIC MSQualityIndicator *ms_quality_indicator_new(RtpSession *session); MS2_PUBLIC MSQualityIndicator *ms_quality_indicator_new(RtpSession *session);
/**
* Set a label, just used for logging.
**/
MS2_PUBLIC void ms_quality_indicator_set_label(MSQualityIndicator *obj, const char *label);
/** /**
* Updates quality indicator based on a received RTCP packet. * Updates quality indicator based on a received RTCP packet.
**/ **/
......
...@@ -766,6 +766,7 @@ AudioStream *audio_stream_new_with_sessions(const MSMediaStreamSessions *session ...@@ -766,6 +766,7 @@ AudioStream *audio_stream_new_with_sessions(const MSMediaStreamSessions *session
stream->ms.rtpsend=ms_filter_new(MS_RTP_SEND_ID); stream->ms.rtpsend=ms_filter_new(MS_RTP_SEND_ID);
stream->ms.ice_check_list=NULL; stream->ms.ice_check_list=NULL;
stream->ms.qi=ms_quality_indicator_new(stream->ms.sessions.rtp_session); stream->ms.qi=ms_quality_indicator_new(stream->ms.sessions.rtp_session);
ms_quality_indicator_set_label(stream->ms.qi,"audio");
stream->ms.process_rtcp=audio_stream_process_rtcp; stream->ms.process_rtcp=audio_stream_process_rtcp;
if (ec_desc!=NULL){ if (ec_desc!=NULL){
stream->ec=ms_filter_new_from_desc(ec_desc); stream->ec=ms_filter_new_from_desc(ec_desc);
......
...@@ -469,23 +469,8 @@ static void media_stream_process_rtcp(MediaStream *stream, mblk_t *m, time_t cur ...@@ -469,23 +469,8 @@ static void media_stream_process_rtcp(MediaStream *stream, mblk_t *m, time_t cur
stream->last_packet_time=curtime; stream->last_packet_time=curtime;
ms_message("%s stream [%p]: receiving RTCP %s%s",media_stream_type_str(stream),stream,(rtcp_is_SR(m)?"SR":""),(rtcp_is_RR(m)?"RR":"")); ms_message("%s stream [%p]: receiving RTCP %s%s",media_stream_type_str(stream),stream,(rtcp_is_SR(m)?"SR":""),(rtcp_is_RR(m)?"RR":""));
do{ do{
const report_block_t *rb=NULL; if (stream->use_rc&&stream->rc) ms_bitrate_controller_process_rtcp(stream->rc,m);
if (rtcp_is_SR(m)){ if (stream->qi) ms_quality_indicator_update_from_feedback(stream->qi,m);
rb=rtcp_SR_get_report_block(m,0);
}else if (rtcp_is_RR(m)){
rb=rtcp_RR_get_report_block(m,0);
}
if (rb){
unsigned int ij;
float rt=rtp_session_get_round_trip_propagation(stream->sessions.rtp_session);
float flost;
ij=report_block_get_interarrival_jitter(rb);
flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0);
ms_message("media_stream_process_rtcp[stream=%p]: remote statistics available for [%s] stream\n\tremote's interarrival jitter=%u\n"
"\tremote's lost packets percentage since last report=%f\n\tround trip time=%f seconds",stream,media_stream_type_str(stream),ij,flost,rt);
if (stream->use_rc&&stream->rc) ms_bitrate_controller_process_rtcp(stream->rc,m);
if (stream->qi) ms_quality_indicator_update_from_feedback(stream->qi,m);
}
stream->process_rtcp(stream,m); stream->process_rtcp(stream,m);
}while(rtcp_next_packet(m)); }while(rtcp_next_packet(m));
......
...@@ -25,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -25,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <math.h> #include <math.h>
#define LOSS_RATE_MIN_INTERVAL 120
/** /**
* Analyses a received RTCP packet. * Analyses a received RTCP packet.
* Returns TRUE is relevant information has been found in the rtcp message, FALSE otherwise. * Returns TRUE is relevant information has been found in the rtcp message, FALSE otherwise.
...@@ -63,6 +65,14 @@ void ms_qos_analyzer_set_on_action_suggested(MSQosAnalyzer *obj, ...@@ -63,6 +65,14 @@ void ms_qos_analyzer_set_on_action_suggested(MSQosAnalyzer *obj,
obj->on_action_suggested_user_pointer=u; obj->on_action_suggested_user_pointer=u;
} }
void ms_qos_analyser_set_label(MSQosAnalyzer *obj, const char *label){
if (obj->label){
ms_free(obj->label);
obj->label=NULL;
}
if (label) obj->label=ms_strdup(label);
}
MSQosAnalyzer *ms_qos_analyzer_ref(MSQosAnalyzer *obj){ MSQosAnalyzer *ms_qos_analyzer_ref(MSQosAnalyzer *obj){
obj->refcnt++; obj->refcnt++;
return obj; return obj;
...@@ -73,6 +83,7 @@ void ms_qos_analyzer_unref(MSQosAnalyzer *obj){ ...@@ -73,6 +83,7 @@ void ms_qos_analyzer_unref(MSQosAnalyzer *obj){
if (obj->refcnt<=0){ if (obj->refcnt<=0){
if (obj->desc->uninit) if (obj->desc->uninit)
obj->desc->uninit(obj); obj->desc->uninit(obj);
if (obj->label) ms_free(obj->label);
ms_free(obj); ms_free(obj);
} }
} }
...@@ -135,13 +146,15 @@ static bool_t simple_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtcp) ...@@ -135,13 +146,15 @@ static bool_t simple_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtcp)
if (pt!=NULL) obj->clockrate=pt->clock_rate; if (pt!=NULL) obj->clockrate=pt->clock_rate;
else return FALSE; else return FALSE;
} }
if (ortp_loss_rate_estimator_process_report_block(obj->lre,rb)){
cur->lost_percentage=100.0*(float)report_block_get_fraction_lost(rb)/256.0; cur->lost_percentage=ortp_loss_rate_estimator_get_value(obj->lre);
cur->int_jitter=1000.0*(float)report_block_get_interarrival_jitter(rb)/(float)obj->clockrate; 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); cur->rt_prop=rtp_session_get_round_trip_propagation(obj->session);
/*
ms_message("MSQosAnalyzer: lost_percentage=%f, int_jitter=%f ms, rt_prop=%fsec", ms_message("MSQosAnalyzer[%s]: lost_percentage=%f, int_jitter=%f ms, rt_prop=%f sec",
cur->lost_percentage,cur->int_jitter,cur->rt_prop); objbase->label ? objbase->label : "", cur->lost_percentage,cur->int_jitter,cur->rt_prop);
*/
}
} }
return rb!=NULL; return rb!=NULL;
} }
...@@ -207,10 +220,17 @@ static bool_t simple_analyzer_has_improved(MSQosAnalyzer *objbase){ ...@@ -207,10 +220,17 @@ static bool_t simple_analyzer_has_improved(MSQosAnalyzer *objbase){
return FALSE; return FALSE;
} }
static void simple_analyzer_uninit(MSQosAnalyzer *objbase){
MSSimpleQosAnalyzer *obj=(MSSimpleQosAnalyzer*)objbase;
ortp_loss_rate_estimator_destroy(obj->lre);
}
static MSQosAnalyzerDesc simple_analyzer_desc={ static MSQosAnalyzerDesc simple_analyzer_desc={
simple_analyzer_process_rtcp, simple_analyzer_process_rtcp,
simple_analyzer_suggest_action, simple_analyzer_suggest_action,
simple_analyzer_has_improved simple_analyzer_has_improved,
NULL,
simple_analyzer_uninit
}; };
MSQosAnalyzer * ms_simple_qos_analyzer_new(RtpSession *session){ MSQosAnalyzer * ms_simple_qos_analyzer_new(RtpSession *session){
...@@ -218,6 +238,7 @@ MSQosAnalyzer * ms_simple_qos_analyzer_new(RtpSession *session){ ...@@ -218,6 +238,7 @@ MSQosAnalyzer * ms_simple_qos_analyzer_new(RtpSession *session){
obj->session=session; obj->session=session;
obj->parent.desc=&simple_analyzer_desc; obj->parent.desc=&simple_analyzer_desc;
obj->parent.type=Simple; obj->parent.type=Simple;
obj->lre=ortp_loss_rate_estimator_new(LOSS_RATE_MIN_INTERVAL, rtp_session_get_seq_number(session));
return (MSQosAnalyzer*)obj; return (MSQosAnalyzer*)obj;
} }
......
...@@ -44,6 +44,7 @@ extern "C" { ...@@ -44,6 +44,7 @@ extern "C" {
typedef struct _MSSimpleQosAnalyzer{ typedef struct _MSSimpleQosAnalyzer{
MSQosAnalyzer parent; MSQosAnalyzer parent;
RtpSession *session; RtpSession *session;
OrtpLossRateEstimator *lre;
int clockrate; int clockrate;
rtpstats_t stats[STATS_HISTORY]; rtpstats_t stats[STATS_HISTORY];
int curindex; int curindex;
......
...@@ -25,11 +25,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -25,11 +25,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define RATING_SCALE 5.0 #define RATING_SCALE 5.0
#define WORSE_JITTER 0.2 #define WORSE_JITTER 0.2
#define WORSE_RT_PROP 5.0 #define WORSE_RT_PROP 5.0
#define SEQ_INTERVAL 120
struct _MSQualityIndicator{ struct _MSQualityIndicator{
RtpSession *session; RtpSession *session;
char *label;
OrtpLossRateEstimator *lr_estimator;
int clockrate; int clockrate;
double sum_ratings; double sum_ratings;
double sum_lq_ratings; double sum_lq_ratings;
...@@ -50,6 +52,7 @@ struct _MSQualityIndicator{ ...@@ -50,6 +52,7 @@ struct _MSQualityIndicator{
MSQualityIndicator *ms_quality_indicator_new(RtpSession *session){ MSQualityIndicator *ms_quality_indicator_new(RtpSession *session){
MSQualityIndicator *qi=ms_new0(MSQualityIndicator,1); MSQualityIndicator *qi=ms_new0(MSQualityIndicator,1);
qi->session=session; qi->session=session;
qi->lr_estimator=ortp_loss_rate_estimator_new(SEQ_INTERVAL,rtp_session_get_seq_number(qi->session));
qi->rating=5.0; qi->rating=5.0;
qi->lq_rating=5.0; qi->lq_rating=5.0;
qi->local_rating=1.0; qi->local_rating=1.0;
...@@ -59,6 +62,14 @@ MSQualityIndicator *ms_quality_indicator_new(RtpSession *session){ ...@@ -59,6 +62,14 @@ MSQualityIndicator *ms_quality_indicator_new(RtpSession *session){
return qi; return qi;
} }
void ms_quality_indicator_set_label(MSQualityIndicator *obj, const char *label){
if (obj->label){
ms_free(obj->label);
obj->label=NULL;
}
if (label) obj->label=ms_strdup(label);
}
float ms_quality_indicator_get_rating(const MSQualityIndicator *qi){ float ms_quality_indicator_get_rating(const MSQualityIndicator *qi){
return qi->rating; return qi->rating;
} }
...@@ -114,7 +125,7 @@ void ms_quality_indicator_update_from_feedback(MSQualityIndicator *qi, mblk_t *r ...@@ -114,7 +125,7 @@ void ms_quality_indicator_update_from_feedback(MSQualityIndicator *qi, mblk_t *r
}else if (rtcp_is_RR(rtcp)){ }else if (rtcp_is_RR(rtcp)){
rb=rtcp_RR_get_report_block(rtcp,0); rb=rtcp_RR_get_report_block(rtcp,0);
}else{ }else{
ms_warning("ms_quality_indicator_update_from_feedback(): not a RTCP report"); return;
} }
if (qi->clockrate==0){ if (qi->clockrate==0){
PayloadType *pt=rtp_profile_get_payload(rtp_session_get_send_profile(qi->session),rtp_session_get_send_payload_type(qi->session)); PayloadType *pt=rtp_profile_get_payload(rtp_session_get_send_profile(qi->session),rtp_session_get_send_payload_type(qi->session));
...@@ -122,12 +133,22 @@ void ms_quality_indicator_update_from_feedback(MSQualityIndicator *qi, mblk_t *r ...@@ -122,12 +133,22 @@ void ms_quality_indicator_update_from_feedback(MSQualityIndicator *qi, mblk_t *r
else return; else return;
} }
if (rb){ if (rb){
float loss_rate=(float)report_block_get_fraction_lost(rb)/256.0; float loss_rate;
float inter_jitter=(float)report_block_get_interarrival_jitter(rb)/(float)qi->clockrate; float inter_jitter=(float)report_block_get_interarrival_jitter(rb)/(float)qi->clockrate;
float rt_prop=rtp_session_get_round_trip_propagation(qi->session); float rt_prop=rtp_session_get_round_trip_propagation(qi->session);
qi->remote_rating=compute_rating(loss_rate,inter_jitter,0,rt_prop); bool_t new_value;
qi->remote_lq_rating=compute_lq_rating(loss_rate,inter_jitter,0);
new_value=ortp_loss_rate_estimator_process_report_block(qi->lr_estimator,rb);
loss_rate=ortp_loss_rate_estimator_get_value(qi->lr_estimator);
qi->remote_rating=compute_rating(loss_rate/100.0,inter_jitter,0,rt_prop);
qi->remote_lq_rating=compute_lq_rating(loss_rate/100.0,inter_jitter,0);
update_global_rating(qi); update_global_rating(qi);
if (new_value){
ms_message("MSQualityIndicator[%p][%s], remote statistics available:",qi,qi->label ? qi->label : "no label");
ms_message("Loss-rate:\t\t%f",loss_rate);
ms_message("Interarrival-Jitter:\t%f s",inter_jitter);
ms_message("RT-propagation:\t%f s",rt_prop);
}
} }
} }
...@@ -191,6 +212,7 @@ float ms_quality_indicator_get_local_late_rate(const MSQualityIndicator *qi){ ...@@ -191,6 +212,7 @@ float ms_quality_indicator_get_local_late_rate(const MSQualityIndicator *qi){
} }
void ms_quality_indicator_destroy(MSQualityIndicator *qi){ void ms_quality_indicator_destroy(MSQualityIndicator *qi){
ortp_loss_rate_estimator_destroy(qi->lr_estimator);
ms_free(qi); ms_free(qi);
} }
......
...@@ -196,6 +196,7 @@ VideoStream *video_stream_new_with_sessions(const MSMediaStreamSessions *session ...@@ -196,6 +196,7 @@ VideoStream *video_stream_new_with_sessions(const MSMediaStreamSessions *session
stream->ms.type = VideoStreamType; stream->ms.type = VideoStreamType;
stream->ms.sessions=*sessions; stream->ms.sessions=*sessions;
stream->ms.qi=ms_quality_indicator_new(stream->ms.sessions.rtp_session); stream->ms.qi=ms_quality_indicator_new(stream->ms.sessions.rtp_session);
ms_quality_indicator_set_label(stream->ms.qi,"audio");
stream->ms.evq=ortp_ev_queue_new(); stream->ms.evq=ortp_ev_queue_new();
stream->ms.rtpsend=ms_filter_new(MS_RTP_SEND_ID); stream->ms.rtpsend=ms_filter_new(MS_RTP_SEND_ID);
stream->ms.ice_check_list=NULL; stream->ms.ice_check_list=NULL;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment