Add possibility to change adaptive rate algorithm at runtime

parent 0bbb51b5
......@@ -94,8 +94,16 @@ struct _MSQosAnalyzerDesc{
void (*uninit)(MSQosAnalyzer *);
};
enum _MSQosAnalyzerAlgorithm {
MSQosAnalyzerAlgorithmSimple,
MSQosAnalyzerAlgorithmStateful
};
typedef enum _MSQosAnalyzerAlgorithm MSQosAnalyzerAlgorithm;
const char* ms_qos_analyzer_algorithm_to_string(MSQosAnalyzerAlgorithm alg);
/**
* A MSQosAnalyzer is responsible to analyze RTCP feedback and suggest actions on bitrate or packet rate accordingly.
* A MSQosAnalyzer is responsible to analyze RTCP feedback and suggest
* actions on bitrate or packet rate accordingly.
* This is an abstract interface.
**/
struct _MSQosAnalyzer{
......@@ -105,12 +113,10 @@ struct _MSQosAnalyzer{
void (*on_action_suggested)(void*, int, const char**);
void *on_action_suggested_user_pointer;
int refcnt;
enum {
Simple,
Stateful,
} type;
MSQosAnalyzerAlgorithm type;
};
MS2_PUBLIC MSQosAnalyzer * ms_qos_analyzer_ref(MSQosAnalyzer *obj);
MS2_PUBLIC void ms_qos_analyzer_unref(MSQosAnalyzer *obj);
MS2_PUBLIC void ms_qos_analyser_set_label(MSQosAnalyzer *obj, const char *label);
......
......@@ -140,7 +140,8 @@ struct _MediaStream {
time_t last_iterate_time;
uint64_t last_packet_count;
time_t last_packet_time;
bool_t use_rc;
bool_t rc_enable;
MSQosAnalyzerAlgorithm rc_algorithm;
bool_t is_beginning;
bool_t owns_sessions;
bool_t pad;
......@@ -167,6 +168,8 @@ MS2_PUBLIC int media_stream_set_dscp(MediaStream *stream, int dscp);
MS2_PUBLIC void media_stream_enable_adaptive_bitrate_control(MediaStream *stream, bool_t enabled);
MS2_PUBLIC void media_stream_set_adaptive_bitrate_algorithm(MediaStream *stream, MSQosAnalyzerAlgorithm algorithm);
MS2_PUBLIC void media_stream_enable_adaptive_jittcomp(MediaStream *stream, bool_t enabled);
/*
......
......@@ -311,9 +311,9 @@ static void unplumb_av_player(AudioStream *stream){
struct _AVPlayer *player=&stream->av_player;
MSConnectionHelper ch;
bool_t reattach=stream->ms.state==MSStreamStarted;
if (!player->plumbed) return;
if (player->videopin!=-1){
ms_connection_helper_start(&ch);
ms_connection_helper_unlink(&ch,player->player,-1,player->videopin);
......@@ -332,7 +332,7 @@ static void unplumb_av_player(AudioStream *stream){
static void close_av_player(AudioStream *stream){
struct _AVPlayer *player=&stream->av_player;
if (player->player){
MSPlayerState st=MSPlayerClosed;
unplumb_av_player(stream);
......@@ -365,7 +365,7 @@ static void configure_av_player(AudioStream *stream, const MSFmtDescriptor *audi
}
ms_filter_call_method(player->resampler,MS_FILTER_SET_NCHANNELS,(void*)&audiofmt->nchannels);
ms_filter_call_method(player->resampler,MS_FILTER_SET_SAMPLE_RATE,(void*)&audiofmt->rate);
ms_filter_call_method(stream->outbound_mixer,MS_FILTER_GET_SAMPLE_RATE,&stream_rate);
ms_filter_call_method(stream->outbound_mixer,MS_FILTER_GET_NCHANNELS,&stream_channels);
ms_filter_call_method(player->resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&stream_channels);
......@@ -382,7 +382,7 @@ static void plumb_av_player(AudioStream *stream){
struct _AVPlayer *player=&stream->av_player;
MSConnectionHelper ch;
bool_t reattach=stream->ms.state==MSStreamStarted;
if (player->videopin!=-1){
ms_connection_helper_start(&ch);
ms_connection_helper_link(&ch,player->player,-1,player->videopin);
......@@ -405,7 +405,7 @@ static int open_av_player(AudioStream *stream, const char *filename){
MSPinFormat fmt1={0},fmt2={0};
MSPinFormat *audiofmt=NULL;
MSPinFormat *videofmt=NULL;
if (player->player) close_av_player(stream);
player->player=create_av_player(filename);
if (player->player==NULL){
......@@ -744,7 +744,7 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
}
ms_filter_call_method(stream->ec,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
}
stream->outbound_mixer=ms_filter_new(MS_AUDIO_MIXER_ID);
if (stream->features & AUDIO_STREAM_FEATURE_MIXED_RECORDING) setup_recorder(stream,sample_rate,nchannels);
......@@ -796,13 +796,15 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
audio_stream_configure_resampler(stream->write_resampler,stream->ms.decoder,stream->soundwrite,pt->clock_rate,8000);
}
if (stream->ms.use_rc){
stream->ms.rc=
#if LINPHONE_NEW_WIP_QOS_ANALYZER_ALGO
ms_bandwidth_bitrate_controller_new(stream->ms.sessions.rtp_session,stream->ms.encoder, NULL, NULL);
#else
ms_audio_bitrate_controller_new(stream->ms.sessions.rtp_session,stream->ms.encoder,0);
#endif
if (stream->ms.rc_enable){
switch (stream->ms.rc_algorithm){
case MSQosAnalyzerAlgorithmSimple:
stream->ms.rc=ms_audio_bitrate_controller_new(stream->ms.sessions.rtp_session,stream->ms.encoder,0);
break;
case MSQosAnalyzerAlgorithmStateful:
stream->ms.rc=ms_bandwidth_bitrate_controller_new(stream->ms.sessions.rtp_session,stream->ms.encoder, NULL, NULL);
break;
}
}
/* Create generic PLC if not handled by the decoder directly*/
......@@ -830,7 +832,7 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
if (stream->features & AUDIO_STREAM_FEATURE_LOCAL_PLAYING){
stream->local_mixer=ms_filter_new(MS_AUDIO_MIXER_ID);
}
ms_filter_call_method(stream->outbound_mixer,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
ms_filter_call_method(stream->outbound_mixer,MS_FILTER_SET_NCHANNELS,&nchannels);
......
......@@ -239,7 +239,11 @@ int media_stream_set_dscp(MediaStream *stream, int dscp) {
}
void media_stream_enable_adaptive_bitrate_control(MediaStream *stream, bool_t enabled) {
stream->use_rc = enabled;
stream->rc_enable = enabled;
}
void media_stream_set_adaptive_bitrate_algorithm(MediaStream *stream, MSQosAnalyzerAlgorithm algorithm) {
stream->rc_algorithm = algorithm;
}
void media_stream_enable_adaptive_jittcomp(MediaStream *stream, bool_t enabled) {
......@@ -470,7 +474,7 @@ static void media_stream_process_rtcp(MediaStream *stream, mblk_t *m, time_t cur
stream->last_packet_time=curtime;
ms_message("%s stream [%p]: receiving RTCP %s%s",media_stream_type_str(stream),stream,(rtcp_is_SR(m)?"SR":""),(rtcp_is_RR(m)?"RR":""));
do{
if (stream->use_rc&&stream->rc) ms_bitrate_controller_process_rtcp(stream->rc,m);
if (stream->rc_enable&&stream->rc) ms_bitrate_controller_process_rtcp(stream->rc,m);
if (stream->qi) ms_quality_indicator_update_from_feedback(stream->qi,m);
stream->process_rtcp(stream,m);
}while(rtcp_next_packet(m));
......
......@@ -76,14 +76,18 @@ void ms_qos_analyser_set_label(MSQosAnalyzer *obj, const char *label){
if (label) obj->label=ms_strdup(label);
}
const char* ms_qos_analyzer_get_name(MSQosAnalyzer *obj){
switch (obj->type){
case Simple: return "Simple";
case Stateful: return "Stateful";
default: return "Unknown";
const char* ms_qos_analyzer_algorithm_to_string(MSQosAnalyzerAlgorithm alg) {
switch (alg){
case MSQosAnalyzerAlgorithmSimple: return "Simple";
case MSQosAnalyzerAlgorithmStateful: return "Stateful";
default: return NULL;
}
}
const char* ms_qos_analyzer_get_name(MSQosAnalyzer *obj){
return ms_qos_analyzer_algorithm_to_string(obj->type);
}
MSQosAnalyzer *ms_qos_analyzer_ref(MSQosAnalyzer *obj){
obj->refcnt++;
return obj;
......@@ -250,7 +254,7 @@ MSQosAnalyzer * ms_simple_qos_analyzer_new(RtpSession *session){
MSSimpleQosAnalyzer *obj=ms_new0(MSSimpleQosAnalyzer,1);
obj->session=session;
obj->parent.desc=&simple_analyzer_desc;
obj->parent.type=Simple;
obj->parent.type=MSQosAnalyzerAlgorithmSimple;
obj->parent.lre=ortp_loss_rate_estimator_new(LOSS_RATE_MIN_INTERVAL, session);
return (MSQosAnalyzer*)obj;
}
......@@ -630,7 +634,7 @@ MSQosAnalyzer * ms_stateful_qos_analyzer_new(RtpSession *session){
MSStatefulQosAnalyzer *obj=ms_new0(MSStatefulQosAnalyzer,1);
obj->session=session;
obj->parent.desc=&stateful_analyzer_desc;
obj->parent.type=Stateful;
obj->parent.type=MSQosAnalyzerAlgorithmStateful;
obj->parent.lre=ortp_loss_rate_estimator_new(LOSS_RATE_MIN_INTERVAL, session);
/*burst period will float the upload bandwidth assuming 5 sec RTCP reports interval*/
......
......@@ -453,13 +453,15 @@ static void configure_video_source(VideoStream *stream){
ms_bitrate_controller_destroy(stream->ms.rc);
stream->ms.rc=NULL;
}
if (stream->ms.use_rc){
stream->ms.rc=
#if LINPHONE_NEW_WIP_QOS_ANALYZER_ALGO
ms_bandwidth_bitrate_controller_new(NULL, NULL, stream->ms.sessions.rtp_session,stream->ms.encoder);
#else
ms_av_bitrate_controller_new(NULL,NULL,stream->ms.sessions.rtp_session,stream->ms.encoder);
#endif
if (stream->ms.rc_enable){
switch (stream->ms.rc_algorithm){
case MSQosAnalyzerAlgorithmSimple:
stream->ms.rc=ms_av_bitrate_controller_new(NULL,NULL,stream->ms.sessions.rtp_session,stream->ms.encoder);
break;
case MSQosAnalyzerAlgorithmStateful:
stream->ms.rc=ms_bandwidth_bitrate_controller_new(NULL, NULL, stream->ms.sessions.rtp_session,stream->ms.encoder);
break;
}
}
}
......
......@@ -199,9 +199,9 @@ static void handle_queue_events(stream_manager_t * stream_mgr) {
if (rb){
stream_mgr->rtcp_count++;
if (stream_mgr->type==MSVideo && stream_mgr->video_stream->ms.use_rc){
if (stream_mgr->type==MSVideo && stream_mgr->video_stream->ms.rc_enable){
const MSQosAnalyzer *analyzer=ms_bitrate_controller_get_qos_analyzer(stream_mgr->video_stream->ms.rc);
if (analyzer->type==Stateful){
if (analyzer->type==MSQosAnalyzerAlgorithmStateful){
const MSStatefulQosAnalyzer *stateful_analyzer=((const MSStatefulQosAnalyzer*)analyzer);
stream_mgr->adaptive_stats.network_state=stateful_analyzer->network_state;
stream_mgr->adaptive_stats.loss_estim =100*stateful_analyzer->network_loss_rate;
......@@ -245,6 +245,7 @@ void start_adaptive_stream(MSFormatType type, stream_manager_t ** pmarielle, str
media_stream_enable_adaptive_bitrate_control(marielle_ms,TRUE);
media_stream_set_adaptive_bitrate_algorithm(marielle_ms, MSQosAnalyzerAlgorithmStateful);
rtp_session_set_duplication_ratio(marielle_ms->sessions.rtp_session, dup_ratio);
if (marielle->type == MSAudio){
......
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