Add tester for loss rate estimator

parent 1b8a4cff
......@@ -173,7 +173,7 @@ static bool_t simple_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtcp)
if (pt!=NULL) obj->clockrate=pt->clock_rate;
else return FALSE;
}
if (ortp_loss_rate_estimator_process_report_block(objbase->lre,rb)){
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);
......@@ -300,15 +300,6 @@ static float stateful_qos_analyzer_upload_bandwidth(MSStatefulQosAnalyzer *obj){
return obj->upload_bandwidth_latest;
}
static int stateful_qos_analyzer_get_total_emitted(const MSStatefulQosAnalyzer *obj, const report_block_t *rb){
float dup = obj->burst_ratio;
int burst_within_start = MAX(obj->previous_ext_high_seq_num_rec, obj->start_seq_number);
int burst_within_end = MIN(report_block_get_high_ext_seq(rb), obj->last_seq_number);
int uniq_emitted=report_block_get_high_ext_seq(rb) - obj->previous_ext_high_seq_num_rec;
return uniq_emitted + MAX(0,burst_within_end - burst_within_start) * dup;
}
static bool_t stateful_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtcp){
MSStatefulQosAnalyzer *obj=(MSStatefulQosAnalyzer*)objbase;
const report_block_t *rb=NULL;
......@@ -319,12 +310,8 @@ static bool_t stateful_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtc
}
if (rb && report_block_get_ssrc(rb)==rtp_session_get_send_ssrc(obj->session)){
if (ortp_loss_rate_estimator_process_report_block(objbase->lre,rb)){
int total_emitted=stateful_qos_analyzer_get_total_emitted(obj, rb);
int uniq_emitted=report_block_get_high_ext_seq(rb) - obj->previous_ext_high_seq_num_rec;
int cum_loss=report_block_get_cum_packet_loss(rb);
int cum_loss_curr=cum_loss - obj->cum_loss_prev;
float loss_rate = (float)report_block_get_fraction_lost(rb)/256.0;
if (ortp_loss_rate_estimator_process_report_block(objbase->lre,&obj->session->rtp,rb)){
float loss_rate = ortp_loss_rate_estimator_get_value(objbase->lre);
float up_bw = stateful_qos_analyzer_upload_bandwidth(obj);
obj->curindex++;
......@@ -334,14 +321,10 @@ static bool_t stateful_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtc
return FALSE;
}
if (obj->previous_ext_high_seq_num_rec > 0){
loss_rate=(1. - (uniq_emitted - cum_loss_curr) * 1.f / total_emitted);
}
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);/*ortp_loss_rate_estimator_get_value(objbase->lre);*/
obj->latest->loss_percent=MAX(0,loss_rate);/**/
obj->latest->rtt=rtp_session_get_round_trip_propagation(obj->session);
obj->rtcpstatspoint=ms_list_insert_sorted(obj->rtcpstatspoint, obj->latest, (MSCompareFunc)sort_points);
......@@ -591,7 +574,6 @@ static void stateful_analyzer_update(MSQosAnalyzer *objbase){
obj->burst_state=MSStatefulQosAnalyzerBurstInProgress;
ortp_gettimeofday(&obj->start_time, NULL);
rtp_session_set_duplication_ratio(obj->session, obj->burst_ratio);
obj->start_seq_number=obj->last_seq_number=obj->session->rtp.snd_seq;
} case MSStatefulQosAnalyzerBurstInProgress: {
struct timeval now;
float elapsed;
......@@ -599,8 +581,6 @@ static void stateful_analyzer_update(MSQosAnalyzer *objbase){
ortp_gettimeofday(&now,NULL);
elapsed=((now.tv_sec-obj->start_time.tv_sec)*1000.0) + ((now.tv_usec-obj->start_time.tv_usec)/1000.0);
obj->last_seq_number=obj->session->rtp.snd_seq;
if (elapsed > obj->burst_duration_ms){
obj->burst_state=MSStatefulQosAnalyzerBurstDisable;
rtp_session_set_duplication_ratio(obj->session, 0);
......
......@@ -83,11 +83,6 @@ extern "C" {
double burst_ratio;
double burst_duration_ms;
uint32_t start_seq_number;
uint32_t last_seq_number;
int cum_loss_prev;
int previous_ext_high_seq_num_rec;
}MSStatefulQosAnalyzer;
#ifdef __cplusplus
}
......
......@@ -138,7 +138,7 @@ void ms_quality_indicator_update_from_feedback(MSQualityIndicator *qi, mblk_t *r
float rt_prop=rtp_session_get_round_trip_propagation(qi->session);
bool_t new_value;
new_value=ortp_loss_rate_estimator_process_report_block(qi->lr_estimator,rb);
new_value=ortp_loss_rate_estimator_process_report_block(qi->lr_estimator,&qi->session->rtp,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);
......
......@@ -390,6 +390,63 @@ static void upload_bandwidth_computation() {
}
}
typedef struct {
OrtpLossRateEstimator *estimator;
OrtpEvQueue *q;
int loss_rate;
}LossRateEstimatorCtx;
static void event_queue_cb(MediaStream *ms, void *user_pointer) {
LossRateEstimatorCtx *ctx = (LossRateEstimatorCtx*)user_pointer;
if (ctx->q != NULL) {
OrtpEvent *ev = NULL;
while ((ev = ortp_ev_queue_get(ctx->q)) != NULL) {
OrtpEventType evt = ortp_event_get_type(ev);
OrtpEventData *evd = ortp_event_get_data(ev);
if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
do {
const report_block_t *rb=NULL;
if (rtcp_is_SR(evd->packet)){
rb=rtcp_SR_get_report_block(evd->packet,0);
}else if (rtcp_is_RR(evd->packet)){
rb=rtcp_RR_get_report_block(evd->packet,0);
}
if (rb&&ortp_loss_rate_estimator_process_report_block(ctx->estimator,&ms->sessions.rtp_session->rtp,rb)){
float diff = fabs(ortp_loss_rate_estimator_get_value(ctx->estimator) - ctx->loss_rate);
CU_ASSERT_IN_RANGE(diff, 0, 10);
}
} while (rtcp_next_packet(evd->packet));
}
ortp_event_destroy(ev);
}
}
}
static void loss_rate_estimation() {
bool_t supported = ms_filter_codec_supported("pcma");
if( supported ) {
LossRateEstimatorCtx ctx;
stream_manager_t * marielle, * margaux;
int loss_rate = 15;
start_adaptive_stream(MSAudio, &marielle, &margaux, PCMA8_PAYLOAD_TYPE, 8000, 0, loss_rate, 0, 0);
ctx.estimator=ortp_loss_rate_estimator_new(120, marielle->audio_stream->ms.sessions.rtp_session);
ctx.q = ortp_ev_queue_new();
rtp_session_register_event_queue(marielle->audio_stream->ms.sessions.rtp_session, ctx.q);
ctx.loss_rate = loss_rate;
/*loss rate should be the initial one*/
wait_for_until_with_parse_events(&marielle->audio_stream->ms, &margaux->audio_stream->ms, &loss_rate, 100, 10000, event_queue_cb,&ctx,NULL,NULL);
/*let's set some duplication. loss rate should NOT be changed */
rtp_session_set_duplication_ratio(marielle->audio_stream->ms.sessions.rtp_session, 10);
wait_for_until_with_parse_events(&marielle->audio_stream->ms, &margaux->audio_stream->ms, &loss_rate, 100, 10000, event_queue_cb,&ctx,NULL,NULL);
stop_adaptive_stream(marielle,margaux);
ortp_loss_rate_estimator_destroy(ctx.estimator);
ortp_ev_queue_destroy(ctx.q);
}
}
static void adaptive_vp8() {
ms_warning("Temporary disabled %s",__FUNCTION__);
#if 0
......@@ -431,11 +488,11 @@ static void packet_duplication() {
media_stream_enable_adaptive_bitrate_control(&marielle->audio_stream->ms,FALSE);
iterate_adaptive_stream(marielle, margaux, 100000, &marielle->rtcp_count, 2);
stats=rtp_session_get_stats(margaux->video_stream->ms.sessions.rtp_session);
CU_ASSERT_EQUAL(stats->duplicated, dup_ratio ? stats->packet_recv / (dup_ratio+1) : 0);
CU_ASSERT_EQUAL(stats->packet_dup_recv, dup_ratio ? stats->packet_recv / (dup_ratio+1) : 0);
/*in theory, cumulative loss should be the invert of duplicated count, but
since cumulative loss is computed only on received RTCP report and duplicated
count is updated on each RTP packet received, we cannot accurately compare these values*/
CU_ASSERT_TRUE(stats->cum_packet_loss <= -.5*stats->duplicated);
CU_ASSERT_TRUE(stats->cum_packet_loss <= -.5*stats->packet_dup_recv);
stop_adaptive_stream(marielle,margaux);
dup_ratio = 1;
......@@ -443,14 +500,15 @@ static void packet_duplication() {
media_stream_enable_adaptive_bitrate_control(&marielle->audio_stream->ms,FALSE);
iterate_adaptive_stream(marielle, margaux, 100000, &marielle->rtcp_count, 2);
stats=rtp_session_get_stats(margaux->video_stream->ms.sessions.rtp_session);
CU_ASSERT_EQUAL(stats->duplicated, dup_ratio ? stats->packet_recv / (dup_ratio+1) : 0);
CU_ASSERT_TRUE(stats->cum_packet_loss <= -.5*stats->duplicated);
CU_ASSERT_EQUAL(stats->packet_dup_recv, dup_ratio ? stats->packet_recv / (dup_ratio+1) : 0);
CU_ASSERT_TRUE(stats->cum_packet_loss <= -.5*stats->packet_dup_recv);
stop_adaptive_stream(marielle,margaux);
}
static test_t tests[] = {
{ "Packet duplication", packet_duplication},
{ "Upload bandwidth computation", upload_bandwidth_computation },
{ "Loss rate estimation", loss_rate_estimation },
{ "Adaptive audio stream [opus]", adaptive_opus_audio_stream },
{ "Adaptive audio stream [speex]", adaptive_speex16_audio_stream },
{ "Adaptive audio stream [pcma]", adaptive_pcma_audio_stream },
......
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