Commit 95dbd944 authored by Gautier Pelloux-Prayer's avatar Gautier Pelloux-Prayer
Browse files

add audio encoder support on bitrate driver and fix tests with the current qos analyser

parent d02c0c3e
......@@ -135,7 +135,7 @@ static void audio_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0);
ms_message("audio_stream_iterate[%p]: remote statistics available\n\tremote's interarrival jitter=%u\n"
"\tremote's lost packets percentage since last report=%f\n\tround trip time=%f seconds",stream,ij,flost,rt);
if (stream->ms.rc) ms_bitrate_controller_process_rtcp(stream->ms.rc,m);
if (stream->ms.use_rc&&stream->ms.rc) ms_bitrate_controller_process_rtcp(stream->ms.rc,m);
if (stream->ms.qi) ms_quality_indicator_update_from_feedback(stream->ms.qi,m);
}
}while(rtcp_next_packet(m));
......
......@@ -81,10 +81,9 @@ static void state_machine(MSBitrateController *obj){
break;
case Probing:
obj->stable_count=0;
/* if (ms_qos_analyser_has_improved(obj->analyser)){
if (ms_qos_analyser_has_improved(obj->analyser)){
obj->state=Stable;
}else{*/
{
}else{
ms_qos_analyser_suggest_action(obj->analyser,&action);
if (action.type!=MSRateControlActionDoNothing){
execute_action(obj,&action);
......
......@@ -356,29 +356,31 @@ static int bandwidth_driver_execute_action(MSBitrateDriver *objbase, const MSRat
}
}
if (!obj->venc){
ret=1;
}
switch(action->type){
case MSRateControlActionDecreaseBitrate:
if (obj->venc){
ret=bandwidth_dec_video_bitrate(obj,action);
}
if (ret!=0 && obj->audio_driver){
ret=ms_bitrate_driver_execute_action(obj->audio_driver,action);
}
break;
case MSRateControlActionDecreasePacketRate:
if (obj->audio_driver){
ret=bandwidth_change_ptime((MSAudioBitrateDriver*) obj->audio_driver, 100);
}else{
ret=-1;
ret=1;
}
break;
case MSRateControlActionIncreaseQuality:
if (obj->venc){
ret=bandwidth_inc_video_bitrate(obj,action);
}else{
ret=1;
}
if (ret != 0){
if (obj->audio_driver){
ret=ms_bitrate_driver_execute_action(obj->audio_driver,action);
}
if (ret!=0 && obj->audio_driver){
ret=ms_bitrate_driver_execute_action(obj->audio_driver,action);
}
break;
case MSRateControlActionDoNothing:
......
......@@ -304,7 +304,7 @@ static bool_t stateful_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtc
obj->latest=ms_new0(rtcpstatspoint_t, 1);
obj->latest->timestamp=ms_time(0);
obj->latest->bandwidth=up_bw;
obj->latest->loss_percent=loss_rate;
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);
......@@ -331,21 +331,13 @@ static float lerp(float inf, float sup, float v){
}
static void smooth_values(MSStatefulQosAnalyser *obj){
//smooth values
MSList *it = obj->rtcpstatspoint;
double prev_loss;
rtcpstatspoint_t *curr = (rtcpstatspoint_t *)it->data;
prev_loss = curr->loss_percent;
double prev_loss = curr->loss_percent;
it = it->next;
curr = (rtcpstatspoint_t *)it->data;
/*float w = obj->rtcpstatspoint[i].bandwidth/obj->rtcpstatspoint[i+1].bandwidth;
obj->rtcpstatspoint[i].loss_percent = (prev + obj->rtcpstatspoint[i+1].loss_percent*w)/(1+w);*/
((rtcpstatspoint_t *)it->prev->data)->loss_percent = lerp(prev_loss, curr->loss_percent, .25);
/*obj->rtcpstatspoint[i].loss_percent = MIN(prev, obj->rtcpstatspoint[i+1].loss_percent);*/
/*obj->rtcpstatspoint[i].loss_percent = obj->rtcpstatspoint[i+1].loss_percent;*/
/*float w1 = obj->rtcpstatspoint[i].bandwidth;
float w2 = obj->rtcpstatspoint[i+1].bandwidth;
obj->rtcpstatspoint[i].loss_percent = (w2*prev + w1*obj->rtcpstatspoint[i+1].loss_percent)/(w1+w2);*/
while (it->next != NULL){
curr = (rtcpstatspoint_t *)it->data;
rtcpstatspoint_t *prev = ((rtcpstatspoint_t *)it->prev->data);
......@@ -358,14 +350,7 @@ static void smooth_values(MSStatefulQosAnalyser *obj){
it = it->next;
}
curr = (rtcpstatspoint_t *)it->data;
/*w = obj->rtcpstatspoint[i-1].bandwidth/obj->rtcpstatspoint[i].bandwidth;
obj->rtcpstatspoint[i].loss_percent = (obj->rtcpstatspoint[i].loss_percent + prev*w)/(1+w);*/
curr->loss_percent = lerp(prev_loss, curr->loss_percent, .75);
/*obj->rtcpstatspoint[i].loss_percent = MAX(prev, obj->rtcpstatspoint[i].loss_percent);*/
/*obj->rtcpstatspoint[i].loss_percent = prev;*/
/*w1 = obj->rtcpstatspoint[i-1].bandwidth;
w2 = obj->rtcpstatspoint[i].bandwidth;
obj->rtcpstatspoint[i].loss_percent = (w1*prev + w2*obj->rtcpstatspoint[i].loss_percent)/(w1+w2);*/
}
static float compute_available_bw(MSStatefulQosAnalyser *obj){
......@@ -485,24 +470,8 @@ static void stateful_analyser_suggest_action(MSQosAnalyser *objbase, MSRateContr
}
static bool_t stateful_analyser_has_improved(MSQosAnalyser *objbase){
MSStatefulQosAnalyser *obj=(MSStatefulQosAnalyser*)objbase;
rtpstats_t *cur=&obj->stats[obj->curindex % STATS_HISTORY];
rtpstats_t *prev=&obj->stats[(STATS_HISTORY+obj->curindex-1) % STATS_HISTORY];
if (prev->lost_percentage>=unacceptable_loss_rate){
if (cur->lost_percentage<prev->lost_percentage){
ms_message("MSQosAnalyser: lost percentage has improved");
return TRUE;
}else goto end;
}
if (obj->rt_prop_doubled && cur->rt_prop<prev->rt_prop){
ms_message("MSQosAnalyser: rt prop decreased");
obj->rt_prop_doubled=FALSE;
return TRUE;
}
end:
ms_message("MSQosAnalyser: no improvements.");
/*never tell the controller that situation has improved to avoid 'Stable' state
which is not necessary for this analyser*/
return FALSE;
}
......@@ -516,27 +485,29 @@ static void stateful_analyser_update(MSQosAnalyser *objbase){
}
last_measure = ms_time(0);
switch (obj->burst_state){
case MSStatefulQosAnalyserBurstEnable:{
obj->burst_state=MSStatefulQosAnalyserBurstInProgress;
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 MSStatefulQosAnalyserBurstInProgress: {
struct timeval now;
double elapsed;
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=MSStatefulQosAnalyserBurstDisable;
rtp_session_set_duplication_ratio(obj->session, 0);
if (obj->burst_duration_ms>0){
switch (obj->burst_state){
case MSStatefulQosAnalyserBurstEnable:{
obj->burst_state=MSStatefulQosAnalyserBurstInProgress;
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 MSStatefulQosAnalyserBurstInProgress: {
struct timeval now;
double elapsed;
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=MSStatefulQosAnalyserBurstDisable;
rtp_session_set_duplication_ratio(obj->session, 0);
}
} case MSStatefulQosAnalyserBurstDisable: {
}
}
} case MSStatefulQosAnalyserBurstDisable: {
}
}
}
......
......@@ -110,7 +110,7 @@ static void video_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
i=report_block_get_interarrival_jitter(rb);
flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0);
ms_message("video_stream_process_rtcp[%p]: interarrival jitter=%u , lost packets percentage since last report=%f, round trip time=%f seconds",stream,i,flost,rt);
if (stream->ms.rc) ms_bitrate_controller_process_rtcp(stream->ms.rc,m);
if (stream->ms.use_rc&&stream->ms.rc) ms_bitrate_controller_process_rtcp(stream->ms.rc,m);
if (stream->ms.qi) ms_quality_indicator_update_from_feedback(stream->ms.qi,m);
} else if (rtcp_is_PSFB(m)) {
if (rtcp_PSFB_get_type(m) == RTCP_PSFB_FIR) {
......
......@@ -384,7 +384,7 @@ static void adaptive_speex16_audio_stream() {
OrtpEvQueue * evq;
evq=start_adaptive_stream(AudioStreamType, &marielle, &margaux, SPEEX16_PAYLOAD_TYPE, 32000, EDGE_BW / 2., 0, 0, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(10), &marielle->audio_stats.number_of_EndOfFile, 10);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(9), &marielle->audio_stats.number_of_EndOfFile, 10);
bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./(EDGE_BW / 2.);
CU_ASSERT_IN_RANGE(bw_usage, 1.f, 5.f);
DEINIT();
......@@ -401,7 +401,7 @@ static void adaptive_pcma_audio_stream() {
// yet non-adaptative codecs cannot respect low throughput limitations
evq=start_adaptive_stream(AudioStreamType, &marielle, &margaux, PCMA8_PAYLOAD_TYPE, 8000, EDGE_BW, 0, 0, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(10), &marielle->audio_stats.number_of_EndOfFile, 10);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(9), &marielle->audio_stats.number_of_EndOfFile, 10);
bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./EDGE_BW;
CU_ASSERT_IN_RANGE(bw_usage,6.f, 8.f); // this is bad!
DEINIT();
......@@ -420,19 +420,16 @@ static void upload_bandwidth_computation() {
stream_manager_t * marielle, * margaux;
OrtpEvQueue * evq;
int i;
const MSQosAnalyser *analyser;
evq=start_adaptive_stream(AudioStreamType, &marielle, &margaux, PCMA8_PAYLOAD_TYPE, 8000, 0, 0, 0, 0);
analyser=ms_bitrate_controller_get_qos_analyser(marielle->audio_stream->ms.rc);
if (analyser->type==Stateful){
const MSStatefulQosAnalyser *stateful_analyser=((const MSStatefulQosAnalyser*)analyser);
for (i = 0; i < 5; i++){
rtp_session_set_duplication_ratio(marielle->audio_stream->ms.sessions.rtp_session, i);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(2), NULL, 0);
/*since PCMA uses 80kbit/s, upload bandwidth should just be 80x(duplication_ratio+1) kbits/s */
CU_ASSERT_TRUE(fabs(stateful_analyser->upload_bandwidth_latest - 80.*(i+1)) < 1.f);
}
media_stream_enable_adaptive_bitrate_control(&marielle->audio_stream->ms,FALSE);
for (i = 0; i < 5; i++){
rtp_session_set_duplication_ratio(marielle->audio_stream->ms.sessions.rtp_session, i);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(2), NULL, 0);
/*since PCMA uses 80kbit/s, upload bandwidth should just be 80+80*duplication_ratio kbit/s */
CU_ASSERT_TRUE(fabs(rtp_session_get_send_bandwidth(marielle->audio_stream->ms.sessions.rtp_session)/1000. - 80.*(i+1)) < 1.f);
printf("%f vs %f\n", rtp_session_get_send_bandwidth(marielle->audio_stream->ms.sessions.rtp_session)/1000., 80.*(i+1));
}
DEINIT();
}
......@@ -442,17 +439,17 @@ static void stability_network_detection() {
stream_manager_t * marielle, * margaux;
OrtpEvQueue * evq;
evq=start_adaptive_stream(VideoStreamType, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 0, 0, 500, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(10), NULL, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(9), NULL, 0);
CU_ASSERT_EQUAL(marielle->video_stats.network_state, MSQosAnalyserNetworkFine);
DEINIT();
evq=start_adaptive_stream(VideoStreamType, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 70000, 0, 250,0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(10), NULL, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(9), NULL, 0);
CU_ASSERT_EQUAL(marielle->video_stats.network_state, MSQosAnalyserNetworkCongested);
DEINIT();
evq=start_adaptive_stream(VideoStreamType, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 0, 15, 250,0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(10), NULL, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(9), NULL, 0);
CU_ASSERT_EQUAL(marielle->video_stats.network_state, MSQosAnalyserNetworkLossy);
DEINIT();
}
......@@ -462,27 +459,27 @@ static void adaptive_vp8() {
OrtpEvQueue * evq;
evq=start_adaptive_stream(VideoStreamType, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 0, 25, 50, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(18), NULL, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(17), NULL, 0);
CU_ASSERT_IN_RANGE(marielle->video_stats.loss_estim, 20, 30);
CU_ASSERT_TRUE(marielle->video_stats.congestion_bw_estim > 200);
DEINIT();
/*very low bandwidth cause a lot of packets to be dropped since congestion is
always present even if we are below the limit due to encoding variance*/
/*very low bandwidth causes a lot of packets to be dropped since congestion is
always present even if we are below the limit due to encoder bit-rate variation*/
evq=start_adaptive_stream(VideoStreamType, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 40000, 0, 50,0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(18), NULL, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(17), NULL, 0);
CU_ASSERT_IN_RANGE(marielle->video_stats.loss_estim, 0, 15);
CU_ASSERT_IN_RANGE(marielle->video_stats.congestion_bw_estim, 20, 65);
DEINIT();
evq=start_adaptive_stream(VideoStreamType, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 70000,0, 50,0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(18), NULL, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(17), NULL, 0);
CU_ASSERT_IN_RANGE(marielle->video_stats.loss_estim, 0, 10);
CU_ASSERT_IN_RANGE(marielle->video_stats.congestion_bw_estim, 50, 95);
DEINIT();
evq=start_adaptive_stream(VideoStreamType, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300000, 100000,15, 50,0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(18), NULL, 0);
iterate_adaptive_stream(marielle, margaux, evq, timeout_receive_rtcp(17), NULL, 0);
CU_ASSERT_IN_RANGE(marielle->video_stats.loss_estim, 10, 20);
CU_ASSERT_IN_RANGE(marielle->video_stats.congestion_bw_estim, 80, 125);
DEINIT();
......
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