Commit 9753c73f authored by Ghislain MARY's avatar Ghislain MARY

Add callbacks in the RTP session to get some VOIP metrics.

parent 78e270e5
......@@ -139,6 +139,10 @@ MS2_PUBLIC float media_stream_get_quality_rating(MediaStream *stream);
MS2_PUBLIC float media_stream_get_average_quality_rating(MediaStream *stream);
MS2_PUBLIC float media_stream_get_lq_quality_rating(MediaStream *stream);
MS2_PUBLIC float media_stream_get_average_lq_quality_rating(MediaStream *stream);
/**
* <br>For multirate codecs like OPUS, encoder output target bitrate must be set.
* <br>Encoder will compute output codec bitrate from this value.
......@@ -418,6 +422,12 @@ MS2_PUBLIC float audio_stream_get_quality_rating(AudioStream *stream);
/* returns the quality rating as an average since the start of the streaming session.*/
MS2_PUBLIC float audio_stream_get_average_quality_rating(AudioStream *stream);
/* returns a realtime indicator of the listening quality of the stream between 0 and 5 */
MS2_PUBLIC float audio_stream_get_lq_quality_rating(AudioStream *stream);
/* returns the listening quality rating as an average since the start of the streaming session.*/
MS2_PUBLIC float audio_stream_get_average_lq_quality_rating(AudioStream *stream);
/* enable ZRTP on the audio stream */
MS2_PUBLIC void audio_stream_enable_zrtp(AudioStream *stream, OrtpZrtpParams *params);
......
......@@ -57,6 +57,16 @@ MS2_PUBLIC float ms_quality_indicator_get_rating(MSQualityIndicator *qi);
**/
MS2_PUBLIC float ms_quality_indicator_get_average_rating(MSQualityIndicator *qi);
/**
* Return the real time rating of the listening quality of the session. Its value is between 0.0 (worse) and 5.0 (best).
**/
MS2_PUBLIC float ms_quality_indicator_get_lq_rating(MSQualityIndicator *qi);
/**
* Returns the average rating of the listening quality of the session, that is the rating of the listening quality for all the duration of the session.
**/
MS2_PUBLIC float ms_quality_indicator_get_average_lq_rating(MSQualityIndicator *qi);
/**
* Returns the local loss rate, as computed internally by ms_quality_indicator_update_local().
* The value is expressed as a percentage.
......
......@@ -247,6 +247,52 @@ static void setup_local_player(AudioStream *stream, int samplerate, int channels
ms_filter_add_notify_callback(stream->local_player,player_callback,stream,TRUE);
}
static OrtpRtcpXrPlcStatus audio_stream_get_rtcp_xr_plc_status(unsigned long userdata) {
AudioStream *stream = (AudioStream *)userdata;
if ((stream->features & AUDIO_STREAM_FEATURE_PLC) != 0) {
int decoder_have_plc = 0;
if (ms_filter_has_method(stream->ms.decoder, MS_AUDIO_DECODER_HAVE_PLC)) {
ms_filter_call_method(stream->ms.decoder, MS_AUDIO_DECODER_HAVE_PLC, &decoder_have_plc);
}
if (decoder_have_plc == 0) {
return OrtpRtcpXrSilencePlc;
} else {
return OrtpRtcpXrEnhancedPlc;
}
}
return OrtpRtcpXrNoPlc;
}
static int8_t audio_stream_get_rtcp_xr_signal_level(unsigned long userdata) {
AudioStream *stream = (AudioStream *)userdata;
if ((stream->features & AUDIO_STREAM_FEATURE_VOL_RCV) != 0) {
float volume;
ms_filter_call_method(stream->volrecv, MS_VOLUME_GET_MAX, &volume);
return (int8_t)volume;
}
return ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
}
static int8_t audio_stream_get_rtcp_xr_noise_level(unsigned long userdata) {
AudioStream *stream = (AudioStream *)userdata;
if ((stream->features & AUDIO_STREAM_FEATURE_VOL_RCV) != 0) {
float volume;
ms_filter_call_method(stream->volrecv, MS_VOLUME_GET_MIN, &volume);
return (int8_t)volume;
}
return ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
}
static float audio_stream_get_rtcp_xr_average_quality_rating(unsigned long userdata) {
AudioStream *stream = (AudioStream *)userdata;
return audio_stream_get_average_quality_rating(stream);
}
static float audio_stream_get_rtcp_xr_average_lq_quality_rating(unsigned long userdata) {
AudioStream *stream = (AudioStream *)userdata;
return audio_stream_get_average_lq_quality_rating(stream);
}
int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char *rem_rtp_ip,int rem_rtp_port,
const char *rem_rtcp_ip, int rem_rtcp_port, int payload,int jitt_comp, const char *infile, const char *outfile,
MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec)
......@@ -259,6 +305,14 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
MSRtpPayloadPickerContext picker_context;
bool_t has_builtin_ec=FALSE;
bool_t tricked_sample_rate=FALSE;
const OrtpRtcpXrMediaCallbacks rtcp_xr_media_cbs = {
audio_stream_get_rtcp_xr_plc_status,
audio_stream_get_rtcp_xr_signal_level,
audio_stream_get_rtcp_xr_noise_level,
audio_stream_get_rtcp_xr_average_quality_rating,
audio_stream_get_rtcp_xr_average_lq_quality_rating,
(unsigned long)stream
};
rtp_session_set_profile(rtps,profile);
if (rem_rtp_port>0) rtp_session_set_remote_addr_full(rtps,rem_rtp_ip,rem_rtp_port,rem_rtcp_ip,rem_rtcp_port);
......@@ -267,6 +321,7 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
}
rtp_session_set_payload_type(rtps,payload);
rtp_session_set_jitter_compensation(rtps,jitt_comp);
rtp_session_set_rtcp_xr_media_callbacks(rtps, &rtcp_xr_media_cbs);
if (rem_rtp_port>0)
ms_filter_call_method(stream->ms.rtpsend,MS_RTP_SEND_SET_SESSION,rtps);
......@@ -925,6 +980,14 @@ float audio_stream_get_average_quality_rating(AudioStream *stream){
return media_stream_get_average_quality_rating(&stream->ms);
}
float audio_stream_get_lq_quality_rating(AudioStream *stream) {
return media_stream_get_lq_quality_rating(&stream->ms);
}
float audio_stream_get_average_lq_quality_rating(AudioStream *stream) {
return media_stream_get_average_lq_quality_rating(&stream->ms);
}
void audio_stream_enable_zrtp(AudioStream *stream, OrtpZrtpParams *params){
stream->ms.zrtp_context=ortp_zrtp_context_new(stream->ms.session, params);
}
......@@ -318,6 +318,20 @@ float media_stream_get_average_quality_rating(MediaStream *stream){
return -1;
}
float media_stream_get_lq_quality_rating(MediaStream *stream) {
if (stream->qi) {
return ms_quality_indicator_get_lq_rating(stream->qi);
}
return -1;
}
float media_stream_get_average_lq_quality_rating(MediaStream *stream) {
if (stream->qi) {
return ms_quality_indicator_get_average_lq_rating(stream->qi);
}
return -1;
}
int media_stream_set_target_network_bitrate(MediaStream *stream,int target_bitrate) {
stream->target_bitrate=target_bitrate;
return 0;
......
......@@ -32,9 +32,13 @@ struct _MSQualityIndicator{
RtpSession *session;
int clockrate;
double sum_ratings;
double sum_lq_ratings;
float rating;
float lq_rating; /* Listening-quality rating */
float local_rating;
float remote_rating;
float local_lq_rating; /* Local listening-quality rating */
float remote_lq_rating; /* Remote listening-quality rating */
uint64_t last_packet_count;
uint32_t last_ext_seq;
uint32_t last_late;
......@@ -47,8 +51,11 @@ MSQualityIndicator *ms_quality_indicator_new(RtpSession *session){
MSQualityIndicator *qi=ms_new0(MSQualityIndicator,1);
qi->session=session;
qi->rating=5.0;
qi->lq_rating=5.0;
qi->local_rating=1.0;
qi->remote_rating=1.0;
qi->local_lq_rating=1.0;
qi->remote_lq_rating=1.0;
return qi;
}
......@@ -56,6 +63,10 @@ float ms_quality_indicator_get_rating(MSQualityIndicator *qi){
return qi->rating;
}
float ms_quality_indicator_get_lq_rating(MSQualityIndicator *qi) {
return qi->lq_rating;
}
static float inter_jitter_rating(float inter_jitter){
float tmp=inter_jitter/WORSE_JITTER;
if (tmp>1) tmp=1;
......@@ -83,9 +94,16 @@ static float compute_rating(float loss_rate, float inter_jitter, float late_rate
return loss_rating(loss_rate)*inter_jitter_rating(inter_jitter)*loss_rating(late_rate)*rt_prop_rating(rt_prop);
}
/* Compute listening-quality rating */
static float compute_lq_rating(float loss_rate, float inter_jitter, float late_rate) {
return loss_rating(loss_rate) * inter_jitter_rating(inter_jitter) * loss_rating(late_rate);
}
static void update_global_rating(MSQualityIndicator *qi){
qi->rating=RATING_SCALE*qi->remote_rating*qi->local_rating;
qi->sum_ratings+=qi->rating;
qi->lq_rating=RATING_SCALE*qi->remote_lq_rating*qi->local_lq_rating;
qi->sum_lq_ratings+=qi->lq_rating;
qi->count++;
}
......@@ -108,6 +126,7 @@ void ms_quality_indicator_update_from_feedback(MSQualityIndicator *qi, mblk_t *r
float inter_jitter=(float)report_block_get_interarrival_jitter(rb)/(float)qi->clockrate;
float rt_prop=rtp_session_get_round_trip_propagation(qi->session);
qi->remote_rating=compute_rating(loss_rate,inter_jitter,0,rt_prop);
qi->remote_lq_rating=compute_lq_rating(loss_rate,inter_jitter,0);
update_global_rating(qi);
}
}
......@@ -149,6 +168,7 @@ void ms_quality_indicator_update_local(MSQualityIndicator *qi){
qi->cur_late_rate=late_rate*100.0;
qi->local_rating=compute_rating(loss_rate,0,late_rate,rtp_session_get_round_trip_propagation(qi->session));
qi->local_lq_rating=compute_lq_rating(loss_rate,0,late_rate);
update_global_rating(qi);
}
......@@ -157,6 +177,11 @@ float ms_quality_indicator_get_average_rating(MSQualityIndicator *qi){
return (float)(qi->sum_ratings/(double)qi->count);
}
float ms_quality_indicator_get_average_lq_rating(MSQualityIndicator *qi) {
if (qi->count == 0) return -1; /* No rating available */
return (float)(qi->sum_lq_ratings / (double)qi->count);
}
float ms_quality_indicator_get_local_loss_rate(const MSQualityIndicator *qi){
return qi->cur_loss_rate;
}
......
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