split the old algorithm (simple QoS analyser/av bitrate driver) and the new...

split the old algorithm (simple QoS analyser/av bitrate driver) and the  new algorithm (stateful QoS analyser/bandwidth bitrate driver)
parent 2036653e
......@@ -41,11 +41,18 @@ enum _MSRateControlActionType{
MSRateControlActionDecreasePacketRate,
MSRateControlActionIncreaseQuality,
};
typedef enum _MSRateControlActionType MSRateControlActionType;
const char *ms_rate_control_action_type_name(MSRateControlActionType t);
enum _MSQosAnalyserNetworkState{
MSQosAnalyserNetworkFine,
MSQosAnalyserNetworkUnstable,
MSQosAnalyserNetworkCongested,
MSQosAnalyserNetworkLossy,
};
typedef enum _MSQosAnalyserNetworkState MSQosAnalyserNetworkState;
const char *ms_qos_analyser_network_state_name(MSQosAnalyserNetworkState state);
typedef struct _MSRateControlAction{
MSRateControlActionType type;
int value;
......@@ -60,7 +67,7 @@ struct _MSBitrateDriverDesc{
};
/*
* The MSBitrateDriver has the responsability to execute rate control actions.
* The MSBitrateDriver has the responsibility to execute rate control actions.
* This is an abstract interface.
**/
struct _MSBitrateDriver{
......@@ -74,6 +81,7 @@ void ms_bitrate_driver_unref(MSBitrateDriver *obj);
MSBitrateDriver *ms_audio_bitrate_driver_new(RtpSession *session, MSFilter *encoder);
MSBitrateDriver *ms_av_bitrate_driver_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc);
MSBitrateDriver *ms_bandwidth_bitrate_driver_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc);
typedef struct _MSQosAnalyser MSQosAnalyser;
typedef struct _MSQosAnalyserDesc MSQosAnalyserDesc;
......@@ -94,16 +102,11 @@ struct _MSQosAnalyser{
int refcnt;
};
#define MS_QOS_ANALYSER_NETWORK_FINE 0
#define MS_QOS_ANALYSER_NETWORK_UNSTABLE 1
#define MS_QOS_ANALYSER_NETWORK_CONGESTED 2
#define MS_QOS_ANALYSER_NETWORK_LOSSY 3
MSQosAnalyser * ms_qos_analyser_ref(MSQosAnalyser *obj);
void ms_qos_analyser_unref(MSQosAnalyser *obj);
void ms_qos_analyser_suggest_action(MSQosAnalyser *obj, MSRateControlAction *action);
bool_t ms_qos_analyser_has_improved(MSQosAnalyser *obj);
uint32_t ms_qos_analyser_get_network_state(const MSQosAnalyser *obj);
bool_t ms_qos_analyser_process_rtcp(MSQosAnalyser *obj, mblk_t *rtcp);
/**
......@@ -111,10 +114,11 @@ bool_t ms_qos_analyser_process_rtcp(MSQosAnalyser *obj, mblk_t *rtcp);
**/
MSQosAnalyser * ms_simple_qos_analyser_new(RtpSession *session);
MSQosAnalyser * ms_stateful_qos_analyser_new(RtpSession *session);
/**
* The audio/video qos analyser is an implementation of MSQosAnalyser that performs analysis of two audio and video streams.
**/
MSQosAnalyser * ms_av_qos_analyser_new(RtpSession *asession, RtpSession *vsession);
/*MSQosAnalyser * ms_av_qos_analyser_new(RtpSession *asession, RtpSession *vsession);*/
/**
* The MSBitrateController the overall behavior and state machine of the adaptive rate control system.
......
......@@ -92,12 +92,12 @@ static int apply_ptime(MSAudioBitrateDriver *obj,int target_ptime){
return result;
}
static int inc_ptime(MSAudioBitrateDriver *obj, int percent){
return apply_ptime(obj,obj->min_ptime + (max_ptime - obj->min_ptime) * percent / 100.f);
static int inc_ptime(MSAudioBitrateDriver *obj){
return apply_ptime(obj,obj->cur_ptime+obj->min_ptime);
}
static int dec_ptime(MSAudioBitrateDriver *obj, int percent){
return apply_ptime(obj,obj->min_ptime + (max_ptime - obj->min_ptime) * percent / 100.f);
static int dec_ptime(MSAudioBitrateDriver *obj){
return apply_ptime(obj,obj->cur_ptime-obj->min_ptime);
}
static int audio_bitrate_driver_execute_action(MSBitrateDriver *objbase, const MSRateControlAction *action){
......@@ -122,7 +122,7 @@ static int audio_bitrate_driver_execute_action(MSBitrateDriver *objbase, const M
if (action->type==MSRateControlActionDecreaseBitrate){
/*reducing bitrate of the codec isn't sufficient. Increasing ptime is much more efficient*/
if (inc_ptime(obj,100)){
if (inc_ptime(obj)){
if (obj->nom_bitrate>0){
int cur_br=0;
int new_br;
......@@ -139,7 +139,7 @@ static int audio_bitrate_driver_execute_action(MSBitrateDriver *objbase, const M
ms_message("MSAudioBitrateDriver: Attempting to reduce audio bitrate from %i to %i",cur_br,new_br);
if (ms_filter_call_method(obj->encoder,MS_FILTER_SET_BITRATE,&new_br)!=0){
ms_message("MSAudioBitrateDriver: SET_BITRATE failed, incrementing ptime");
return inc_ptime(obj,100);
return inc_ptime(obj);
} else {
rtp_session_set_target_upload_bandwidth(obj->session, new_br);
}
......@@ -150,7 +150,7 @@ static int audio_bitrate_driver_execute_action(MSBitrateDriver *objbase, const M
}
}
}else if (action->type==MSRateControlActionDecreasePacketRate){
return inc_ptime(obj,100);
return inc_ptime(obj);
}else if (action->type==MSRateControlActionIncreaseQuality){
if (obj->nom_bitrate>0){
if (ms_filter_call_method(obj->encoder,MS_FILTER_GET_BITRATE,&obj->cur_bitrate)==0){
......@@ -170,7 +170,7 @@ static int audio_bitrate_driver_execute_action(MSBitrateDriver *objbase, const M
}
if (obj->cur_ptime>obj->min_ptime){
return dec_ptime(obj,0);
return dec_ptime(obj);
}else return -1;
}
return 0;
......@@ -229,18 +229,14 @@ static int inc_video_bitrate(MSAVBitrateDriver *obj, const MSRateControlAction *
int newbr;
int ret=0;
ms_filter_call_method(obj->venc,MS_FILTER_GET_BITRATE,&obj->cur_bitrate);
if (obj->cur_bitrate==0){
ms_message("MSAVBitrateDriver: current bitrate was not known.");
return -1; /*current bitrate was not known*/
}
newbr=(float)obj->cur_bitrate*(100.0+(float)action->value)/100.0;
if (obj->cur_bitrate==0) return -1; /*current bitrate was not known*/
newbr=(float)obj->cur_bitrate*(1.0+((float)action->value/100.0));
if (newbr>obj->nom_bitrate){
newbr=obj->nom_bitrate;
ret=-1;
}
ms_message("MSAVBitrateDriver: increasing bitrate from %i to %i bps for video encoder.",obj->cur_bitrate,newbr);
obj->cur_bitrate=newbr;
ms_message("MSAVBitrateDriver: increasing bitrate to %i bps for video encoder.",obj->cur_bitrate);
ms_filter_call_method(obj->venc,MS_FILTER_SET_BITRATE,&obj->cur_bitrate);
rtp_session_set_target_upload_bandwidth(obj->vsession, obj->cur_bitrate);
return ret;
......@@ -264,22 +260,14 @@ static int av_driver_execute_action(MSBitrateDriver *objbase, const MSRateContro
case MSRateControlActionDecreasePacketRate:
if (obj->audio_driver){
ret=ms_bitrate_driver_execute_action(obj->audio_driver,action);
}else{
ret=-1;
}
break;
case MSRateControlActionIncreaseQuality:
ret=inc_video_bitrate(obj,action);
if (ret != 0){
if (obj->audio_driver){
ret=ms_bitrate_driver_execute_action(obj->audio_driver,action);
}
}
break;
case MSRateControlActionDoNothing:
break;
}
ms_message("MSAVBitrateDriver: Action %s %s", ms_rate_control_action_type_name(action->type), ret == 0 ? "succeeded" : "failed");
return ret;
}
......@@ -306,3 +294,106 @@ MSBitrateDriver *ms_av_bitrate_driver_new(RtpSession *asession, MSFilter *aenc,
}
typedef struct _MSBandwidthBitrateDriver{
MSBitrateDriver parent;
MSBitrateDriver *audio_driver;
RtpSession *vsession;
MSFilter *venc;
int nom_bitrate;
int cur_bitrate;
}MSBandwidthBitrateDriver;
static int bandwidth_change_ptime(MSAudioBitrateDriver *obj, int percent){
return apply_ptime(obj,obj->min_ptime + (max_ptime - obj->min_ptime) * percent / 100.f);
}
static int bandwidth_dec_video_bitrate(MSBandwidthBitrateDriver *obj, const MSRateControlAction *action){
int new_br;
ms_filter_call_method(obj->venc,MS_FILTER_GET_BITRATE,&obj->cur_bitrate);
new_br=((float)obj->cur_bitrate)*(100.0-(float)action->value)/100.0;
if (new_br<min_video_bitrate){
ms_message("MSBandwidthBitrateDriver: reaching low bound.");
new_br=min_video_bitrate;
}
ms_message("MSBandwidthBitrateDriver: targeting %i bps for video encoder.",new_br);
ms_filter_call_method(obj->venc,MS_FILTER_SET_BITRATE,&new_br);
obj->cur_bitrate=new_br;
return new_br==min_video_bitrate ? -1 : 0;
}
static int bandwidth_inc_video_bitrate(MSBandwidthBitrateDriver *obj, const MSRateControlAction *action){
int newbr;
int ret=0;
ms_filter_call_method(obj->venc,MS_FILTER_GET_BITRATE,&obj->cur_bitrate);
if (obj->cur_bitrate==0){
ms_message("MSBandwidthBitrateDriver: current bitrate was not known.");
return -1; /*current bitrate was not known*/
}
newbr=(float)obj->cur_bitrate*(100.0+(float)action->value)/100.0;
if (newbr>obj->nom_bitrate){
newbr=obj->nom_bitrate;
ret=-1;
}
ms_message("MSBandwidthBitrateDriver: increasing bitrate from %i to %i bps for video encoder.",obj->cur_bitrate,newbr);
obj->cur_bitrate=newbr;
ms_filter_call_method(obj->venc,MS_FILTER_SET_BITRATE,&obj->cur_bitrate);
return ret;
}
static int bandwidth_driver_execute_action(MSBitrateDriver *objbase, const MSRateControlAction *action){
MSBandwidthBitrateDriver *obj=(MSBandwidthBitrateDriver*)objbase;
int ret=0;
if (obj->nom_bitrate==0){
ms_filter_call_method(obj->venc,MS_FILTER_GET_BITRATE,&obj->nom_bitrate);
if (obj->nom_bitrate==0){
ms_warning("MSBandwidthBitrateDriver: Not doing adaptive rate control on video encoder, it does not seem to support that.");
return -1;
}
}
switch(action->type){
case MSRateControlActionDecreaseBitrate:
ret=bandwidth_dec_video_bitrate(obj,action);
break;
case MSRateControlActionDecreasePacketRate:
if (obj->audio_driver){
ret=bandwidth_change_ptime((MSAudioBitrateDriver*) obj->audio_driver, 100);
}else{
ret=-1;
}
break;
case MSRateControlActionIncreaseQuality:
ret=bandwidth_inc_video_bitrate(obj,action);
if (ret != 0){
if (obj->audio_driver){
ret=ms_bitrate_driver_execute_action(obj->audio_driver,action);
}
}
break;
case MSRateControlActionDoNothing:
break;
}
ms_message("MSBandwidthBitrateDriver: Action %s %s", ms_rate_control_action_type_name(action->type), ret == 0 ? "succeeded" : "failed");
return ret;
}
static void bandwidth_bitrate_driver_uninit(MSBitrateDriver *objbase){
}
static MSBitrateDriverDesc bandwidth_bitrate_driver={
bandwidth_driver_execute_action,
bandwidth_bitrate_driver_uninit
};
MSBitrateDriver *ms_bandwidth_bitrate_driver_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc){
MSBandwidthBitrateDriver *obj=ms_new0(MSBandwidthBitrateDriver,1);
obj->parent.desc=&bandwidth_bitrate_driver;
obj->vsession = vsession;
obj->audio_driver=(aenc!=NULL) ? ms_bitrate_driver_ref(ms_audio_bitrate_driver_new(asession,aenc)) : NULL;
obj->venc=venc;
return (MSBitrateDriver*)obj;
}
This diff is collapsed.
......@@ -131,13 +131,13 @@ static void handle_queue_events(video_stream_manager_t * stream_mgr, OrtpEvQueue
stream_mgr->latest_stats.loss=100.0*(float)report_block_get_fraction_lost(rb)/256.0;
stream_mgr->latest_stats.rtt=rtp_session_get_round_trip_propagation(stream_mgr->stream->ms.sessions.rtp_session);
if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED)
stream_mgr->latest_stats.network_state=ms_qos_analyser_get_network_state(ms_bitrate_controller_get_qos_analyser(stream_mgr->stream->ms.rc));
ms_message("mediastreamer2_video_stream_tester: %s RTCP packet: loss=%f, RTT=%f, network_state=%d",
(evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) ? "RECEIVED" : "EMITTED",
stream_mgr->latest_stats.loss,
stream_mgr->latest_stats.rtt,
stream_mgr->latest_stats.network_state);
/*stream_mgr->latest_stats.network_state=ms_qos_analyser_get_network_state(ms_bitrate_controller_get_qos_analyser(stream_mgr->stream->ms.rc));*/
ms_message("mediastreamer2_video_stream_tester: %s RTCP packet: loss=%f, RTT=%f, network_state=%d"
,(evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) ? "RECEIVED" : "EMITTED"
,stream_mgr->latest_stats.loss
,stream_mgr->latest_stats.rtt
,stream_mgr->latest_stats.network_state);
}
}
ortp_event_destroy(ev);
......@@ -231,17 +231,17 @@ static void stability_network_detection() {
video_stream_manager_t * marielle, * margaux;
INIT();
start_adaptive_video_stream(marielle, margaux, VP8_PAYLOAD_TYPE, 300000, 0, 0, 500, 10);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MS_QOS_ANALYSER_NETWORK_FINE);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MSQosAnalyserNetworkFine);
DEINIT();
INIT();
start_adaptive_video_stream(marielle, margaux, VP8_PAYLOAD_TYPE, 300000, 50000, 0, 250, 10);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MS_QOS_ANALYSER_NETWORK_CONGESTED);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MSQosAnalyserNetworkCongested);
DEINIT();
INIT();
start_adaptive_video_stream(marielle, margaux, VP8_PAYLOAD_TYPE, 300000, 0, 15, 250, 10);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MS_QOS_ANALYSER_NETWORK_UNSTABLE);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MSQosAnalyserNetworkUnstable);
DEINIT();
}
......@@ -254,7 +254,7 @@ static void adaptive_vp8() {
has_get_bitrate = ms_filter_call_method(marielle->stream->ms.encoder,MS_FILTER_GET_BITRATE,&bitrate);
CU_ASSERT_EQUAL(has_get_bitrate, 0);
CU_ASSERT_EQUAL(bitrate, 200000);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MS_QOS_ANALYSER_NETWORK_LOSSY);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MSQosAnalyserNetworkLossy);
DEINIT();*/
/*
INIT();
......@@ -262,7 +262,7 @@ static void adaptive_vp8() {
has_get_bitrate = ms_filter_call_method(marielle->stream->ms.encoder,MS_FILTER_GET_BITRATE,&bitrate);
CU_ASSERT_EQUAL(has_get_bitrate, 0);
CU_ASSERT_EQUAL(bitrate, 64000);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MS_QOS_ANALYSER_NETWORK_CONGESTED);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MSQosAnalyserNetworkCongested);
DEINIT();*/
/* INIT();
......@@ -270,7 +270,7 @@ static void adaptive_vp8() {
has_get_bitrate = ms_filter_call_method(marielle->stream->ms.encoder,MS_FILTER_GET_BITRATE,&bitrate);
CU_ASSERT_EQUAL(has_get_bitrate, 0);
CU_ASSERT_EQUAL(bitrate, 64000);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MS_QOS_ANALYSER_NETWORK_FINE);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MSQosAnalyserNetworkFine);
DEINIT();*/
INIT();
......@@ -278,7 +278,7 @@ static void adaptive_vp8() {
has_get_bitrate = ms_filter_call_method(marielle->stream->ms.encoder,MS_FILTER_GET_BITRATE,&bitrate);
CU_ASSERT_EQUAL(has_get_bitrate, 0);
CU_ASSERT_EQUAL(bitrate, 64000);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MS_QOS_ANALYSER_NETWORK_LOSSY);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MSQosAnalyserNetworkLossy);
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