Commit 6215770a authored by Gautier Pelloux-Prayer's avatar Gautier Pelloux-Prayer
Browse files

Fix adaptive algorithm and its test

parent 8a235f29
......@@ -315,20 +315,23 @@ static bool_t stateful_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtc
float up_bw = stateful_qos_analyzer_upload_bandwidth(obj);
obj->curindex++;
// Always skip the 2 first reports, since values might be erroneous due
// Always skip the first report, since values might be erroneous due
// to initialization of multiples objects (encoder/decoder/stats computing..)
// Instead assume loss rate is a good estimation of network capacity
if (obj->curindex==1) {
return FALSE;
obj->network_loss_rate=loss_rate;
return TRUE;
}
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->loss_percent=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);
/*if the measure was 0% loss, reset to 0% every measures below it*/
if (obj->latest->loss_percent < 1e-5){
MSList *it=obj->rtcpstatspoint;
MSList *latest_pos=ms_list_find(obj->rtcpstatspoint,obj->latest);
......@@ -338,7 +341,7 @@ static bool_t stateful_analyzer_process_rtcp(MSQosAnalyzer *objbase, mblk_t *rtc
}
}
ms_message("MSStatefulQosAnalyzer[%p]: one more %d: %f %f",
obj, obj->curindex, obj->latest->bandwidth, obj->latest->loss_percent);
obj, obj->curindex-1, obj->latest->bandwidth, obj->latest->loss_percent);
if (ms_list_size(obj->rtcpstatspoint) > ESTIM_HISTORY){
int prev_size = ms_list_size(obj->rtcpstatspoint);
......@@ -492,35 +495,50 @@ static float compute_available_bw(MSStatefulQosAnalyzer *obj){
static void stateful_analyzer_suggest_action(MSQosAnalyzer *objbase, MSRateControlAction *action){
MSStatefulQosAnalyzer *obj=(MSStatefulQosAnalyzer*)objbase;
float curbw = obj->latest ? obj->latest->bandwidth : 0.f;
float bw = compute_available_bw(obj);
rtcpstatspoint_t* greatest_pt = ms_list_size(obj->rtcpstatspoint) ?
(rtcpstatspoint_t*)ms_list_nth_data(obj->rtcpstatspoint, ms_list_size(obj->rtcpstatspoint)-1)
: NULL;
/*try a burst every 50 seconds (10 RTCP packets)*/
if (obj->curindex % 10 == 0){
ms_message("MSStatefulQosAnalyzer[%p]: try burst!", obj);
obj->burst_state = MSStatefulQosAnalyzerBurstEnable;
}
/*test a min burst to avoid overestimation of available bandwidth but only
if there is some loss*/
else if (greatest_pt!=NULL && greatest_pt->loss_percent>1
&& (obj->curindex % 10 == 2 || obj->curindex % 10 == 3)){
ms_message("MSStatefulQosAnalyzer[%p]: try minimal burst!", obj);
bw *= .33;
}
float curbw;
float bw;
rtcpstatspoint_t* greatest_pt = NULL;
/*if this is the first measure, there is not enough reliable data to use; we
assume loss rate is due to non congestionned network. This is mainly useful
in the case loss rate is high (>30%), to reduce quality even before the second
RTCP report which can be really used.
*/
if (obj->curindex==1){
if (obj->network_loss_rate!=0.f){
action->type=MSRateControlActionDecreaseBitrate;
action->value=obj->network_loss_rate;
}
}else {
curbw = obj->latest ? obj->latest->bandwidth : 0.f;
bw = compute_available_bw(obj);
greatest_pt = ms_list_size(obj->rtcpstatspoint) ?
(rtcpstatspoint_t*)ms_list_nth_data(obj->rtcpstatspoint, ms_list_size(obj->rtcpstatspoint)-1)
: NULL;
/*try a burst every 50 seconds (10 RTCP packets)*/
if (obj->curindex % 10 == 0){
ms_message("MSStatefulQosAnalyzer[%p]: try burst!", obj);
obj->burst_state = MSStatefulQosAnalyzerBurstEnable;
}
/*test a min burst to avoid overestimation of available bandwidth but only
if there is some loss*/
else if (greatest_pt!=NULL && greatest_pt->loss_percent>1
&& (obj->curindex % 10 == 2 || obj->curindex % 10 == 3)){
ms_message("MSStatefulQosAnalyzer[%p]: try minimal burst!", obj);
bw *= .33;
}
/*no bandwidth estimation computed*/
if (bw <= 0 || curbw <= 0){
action->type=MSRateControlActionDoNothing;
action->value=0;
}else if (bw > curbw){
action->type=MSRateControlActionIncreaseQuality;
action->value=MAX(0, 100. * (bw / curbw - 1));
}else{
action->type=MSRateControlActionDecreaseBitrate;
action->value=MAX(10, -100. * (bw / curbw - 1));
/*no bandwidth estimation computed*/
if (bw <= 0 || curbw <= 0){
action->type=MSRateControlActionDoNothing;
action->value=0;
}else if (bw > curbw){
action->type=MSRateControlActionIncreaseQuality;
action->value=MAX(0, 100. * (bw / curbw - 1));
}else{
action->type=MSRateControlActionDecreaseBitrate;
action->value=MAX(10, -100. * (bw / curbw - 1));
}
}
ms_message("MSStatefulQosAnalyzer[%p]: %s of value %d",
......
......@@ -202,8 +202,8 @@ static void handle_queue_events(stream_manager_t * stream_mgr) {
const MSQosAnalyzer *analyzer=ms_bitrate_controller_get_qos_analyzer(stream_mgr->video_stream->ms.rc);
if (analyzer->type==MSQosAnalyzerAlgorithmStateful){
const MSStatefulQosAnalyzer *stateful_analyzer=((const MSStatefulQosAnalyzer*)analyzer);
stream_mgr->adaptive_stats.loss_estim =100*stateful_analyzer->network_loss_rate;
stream_mgr->adaptive_stats.congestion_bw_estim =stateful_analyzer->congestion_bandwidth;
stream_mgr->adaptive_stats.loss_estim=stateful_analyzer->network_loss_rate;
stream_mgr->adaptive_stats.congestion_bw_estim=stateful_analyzer->congestion_bandwidth;
}
}
}
......@@ -213,7 +213,7 @@ static void handle_queue_events(stream_manager_t * stream_mgr) {
}
void start_adaptive_stream(MSFormatType type, stream_manager_t ** pmarielle, stream_manager_t ** pmargaux,
int payload, int initial_bitrate, int target_bw, float loss_rate, int latency, float dup_ratio) {
int payload, int initial_bitrate, int max_bw, float loss_rate, int latency, float dup_ratio) {
int pause_time=0;
PayloadType* pt;
MediaStream *marielle_ms,*margaux_ms;
......@@ -225,7 +225,7 @@ void start_adaptive_stream(MSFormatType type, stream_manager_t ** pmarielle, str
stream_manager_t *margaux=*pmargaux=stream_manager_new(type);
params.enabled=TRUE;
params.loss_rate=loss_rate;
params.max_bandwidth=target_bw;
params.max_bandwidth=max_bw;
params.latency=latency;
if (type == MSAudio){
......@@ -341,9 +341,9 @@ static void adaptive_speex16_audio_stream() {
float bw_usage;
stream_manager_t * marielle, * margaux;
start_adaptive_stream(MSAudio, &marielle, &margaux, SPEEX16_PAYLOAD_TYPE, 32000, EDGE_BW / 2., 0, 0, 0);
iterate_adaptive_stream(marielle, margaux, 10000, NULL, 0);
bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./(EDGE_BW / 2.);
start_adaptive_stream(MSAudio, &marielle, &margaux, SPEEX16_PAYLOAD_TYPE, 32000, EDGE_BW, 0, 0, 0);
iterate_adaptive_stream(marielle, margaux, 15000, NULL, 0);
bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./EDGE_BW;
CU_ASSERT_IN_RANGE(bw_usage, 1.f, 5.f);
stop_adaptive_stream(marielle,margaux);
}
......@@ -448,20 +448,18 @@ static void loss_rate_estimation() {
}
static void adaptive_vp8() {
ms_warning("Temporary disabled %s",__FUNCTION__);
#if 0
stream_manager_t * marielle, * margaux;
start_adaptive_stream(MSVideo, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 0, 25, 50, 0);
start_adaptive_stream(MSVideo, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 0, 0, 50,0);
iterate_adaptive_stream(marielle, margaux, 100000, &marielle->rtcp_count, 12);
CU_ASSERT_IN_RANGE(marielle->adaptive_stats.loss_estim, 20, 30);
CU_ASSERT_IN_RANGE(marielle->adaptive_stats.loss_estim, 0, 1);
CU_ASSERT_TRUE(marielle->adaptive_stats.congestion_bw_estim > 200);
stop_adaptive_stream(marielle,margaux);
start_adaptive_stream(MSVideo, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 45000, 0, 50,0);
start_adaptive_stream(MSVideo, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 0, 25, 50, 0);
iterate_adaptive_stream(marielle, margaux, 100000, &marielle->rtcp_count, 12);
CU_ASSERT_IN_RANGE(marielle->adaptive_stats.loss_estim, 0, 2);
CU_ASSERT_IN_RANGE(marielle->adaptive_stats.congestion_bw_estim, 30, 60);
CU_ASSERT_IN_RANGE(marielle->adaptive_stats.loss_estim, 20, 30);
CU_ASSERT_TRUE(marielle->adaptive_stats.congestion_bw_estim > 200);
stop_adaptive_stream(marielle,margaux);
start_adaptive_stream(MSVideo, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 70000,0, 50,0);
......@@ -475,7 +473,6 @@ static void adaptive_vp8() {
CU_ASSERT_IN_RANGE(marielle->adaptive_stats.loss_estim, 10, 20);
CU_ASSERT_IN_RANGE(marielle->adaptive_stats.congestion_bw_estim, 80, 125);
stop_adaptive_stream(marielle,margaux);
#endif
}
static void packet_duplication() {
......
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