Commit e643594a authored by Simon Morlat's avatar Simon Morlat

new rate control: everything compiles

parent f37f0e86
...@@ -34,15 +34,19 @@ extern "C" { ...@@ -34,15 +34,19 @@ extern "C" {
typedef struct _MSAudioBitrateController MSAudioBitrateController; typedef struct _MSAudioBitrateController MSAudioBitrateController;
enum MSRateControlActionType{ enum _MSRateControlActionType{
MSRateControlActionDoNothing, MSRateControlActionDoNothing,
MSRateControlActionDecreaseBitrate, MSRateControlActionDecreaseBitrate,
MSRateControlActionDecreasePacketRate, MSRateControlActionDecreasePacketRate,
MSRateControlActionIncreaseQuality MSRateControlActionIncreaseQuality
}; };
typedef enum _MSRateControlActionType MSRateControlActionType;
const char *ms_rate_control_action_type_name(MSRateControlActionType t);
typedef struct _MSRateControlAction{ typedef struct _MSRateControlAction{
enum MSRateControlActionType type; MSRateControlActionType type;
int value; int value;
}MSRateControlAction; }MSRateControlAction;
...@@ -50,7 +54,7 @@ typedef struct _MSBitrateDriver MSBitrateDriver; ...@@ -50,7 +54,7 @@ typedef struct _MSBitrateDriver MSBitrateDriver;
typedef struct _MSBitrateDriverDesc MSBitrateDriverDesc; typedef struct _MSBitrateDriverDesc MSBitrateDriverDesc;
struct _MSBitrateDriverDesc{ struct _MSBitrateDriverDesc{
void (*execute_action)(MSBitrateDriver *obj, const MSRateControlAction *action); int (*execute_action)(MSBitrateDriver *obj, const MSRateControlAction *action);
void (*uninit)(MSBitrateDriver *obj); void (*uninit)(MSBitrateDriver *obj);
}; };
...@@ -60,20 +64,24 @@ struct _MSBitrateDriverDesc{ ...@@ -60,20 +64,24 @@ struct _MSBitrateDriverDesc{
**/ **/
struct _MSBitrateDriver{ struct _MSBitrateDriver{
MSBitrateDriverDesc *desc; MSBitrateDriverDesc *desc;
int refcnt;
}; };
void ms_bitrate_driver_execute_action(MSBitrateDriver *obj, const MSRateControlAction *action); int ms_bitrate_driver_execute_action(MSBitrateDriver *obj, const MSRateControlAction *action);
void ms_bitrate_driver_destroy(MSBitrateDriver *obj); MSBitrateDriver * ms_bitrate_driver_ref(MSBitrateDriver *obj);
void ms_bitrate_driver_unref(MSBitrateDriver *obj);
MSBitrateDriver *ms_audio_bitrate_driver_new(MSFilter *encoder);
typedef struct _MSQosAnalyser MSQosAnalyser; typedef struct _MSQosAnalyser MSQosAnalyser;
typedef struct _MSQosAnalyserDesc MSQosAnalyserDesc; typedef struct _MSQosAnalyserDesc MSQosAnalyserDesc;
struct _MSQosAnalyserDesc{ struct _MSQosAnalyserDesc{
bool_t (*process_rtcp)(MSQosAnalyzer *obj, mblk_t *rtcp); bool_t (*process_rtcp)(MSQosAnalyser *obj, mblk_t *rtcp);
void (*suggest_action)(MSQosAnalyzer *obj, MSRateControlAction *action); void (*suggest_action)(MSQosAnalyser *obj, MSRateControlAction *action);
bool_t (*has_improved)(MSQosAnalyzer *obj); bool_t (*has_improved)(MSQosAnalyser *obj);
void uninit(MSQosAnalyzer); void (*uninit)(MSQosAnalyser *);
}; };
/** /**
...@@ -82,21 +90,66 @@ struct _MSQosAnalyserDesc{ ...@@ -82,21 +90,66 @@ struct _MSQosAnalyserDesc{
**/ **/
struct _MSQosAnalyser{ struct _MSQosAnalyser{
MSQosAnalyserDesc *desc; MSQosAnalyserDesc *desc;
int refcnt;
}; };
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);
bool_t ms_qos_analyser_process_rtcp(MSQosAnalyser *obj, mblk_t *rtcp);
/** /**
* The simple qos analyzer is an implementation of MSQosAnalizer that performs analysis for single stream. * The simple qos analyzer is an implementation of MSQosAnalizer that performs analysis for single stream.
**/ **/
MSQosAnalyzer * ms_simple_qos_analyser_new(RtpSession *session); MSQosAnalyser * ms_simple_qos_analyser_new(RtpSession *session);
/**
* The MSBitrateController the overall behavior and state machine of the adaptive rate control system.
* It requires a MSQosAnalyser to obtain analyse of the quality of service, and a MSBitrateDriver
* to run the actions on media streams, like decreasing or increasing bitrate.
**/
typedef struct _MSBitrateController MSBitrateController;
/**
* Instanciates MSBitrateController
* @param qosanalyser a Qos analyser object
* @param driver a bitrate driver object.
* The newly created bitrate controller owns references to the analyser and the driver.
**/
MSBitrateController *ms_bitrate_controller_new(MSQosAnalyser *qosanalyser, MSBitrateDriver *driver);
#define MS_AUDIO_RATE_CONTROL_OPTIMIZE_QUALITY (1) /**
#define MS_AUDIO_RATE_CONTROL_OPTIMIZE_LATENCY (1<<1) * Asks the bitrate controller to process a newly received RTCP packet.
* @param MSBitrateController the bitrate controller object.
* @param rtcp an RTCP packet received for the media session(s) being managed by the controller.
* If the RTCP packet contains useful feedback regarding quality of the media streams received by the far end,
* then the bitrate controller may take decision and execute actions on the local media streams to adapt the
* output bitrate.
**/
void ms_bitrate_controller_process_rtcp(MSBitrateController *obj, mblk_t *rtcp);
MSAudioBitrateController *ms_audio_bitrate_controller_new(RtpSession *session, MSFilter *encoder, unsigned int flags); /**
* Destroys the bitrate controller
*
* If no other entity holds references to the underlyings MSQosAnalyser and MSBitrateDriver object,
* then they will be destroyed too.
**/
void ms_bitrate_controller_destroy(MSBitrateController *obj);
void ms_audio_bitrate_controller_process_rtcp(MSAudioBitrateController *obj, mblk_t *rtcp);
void ms_audio_bitrate_controller_destroy(MSAudioBitrateController *obj); /**
* Convenience function to create a bitrate controller managing a single audio stream.
* @param session the RtpSession object for the media stream
* @param encoder the MSFilter object responsible for encoding the audio data.
* @param flags unused.
* This function actually calls internally:
* <br>
* \code
* ms_bitrate_controller_new(ms_simple_qos_analyser_new(session),ms_audio_bitrate_driver_new(encoder));
* \endcode
**/
MSBitrateController *ms_audio_bitrate_controller_new(RtpSession *session, MSFilter *encoder, unsigned int flags);
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -64,7 +64,7 @@ struct _AudioStream ...@@ -64,7 +64,7 @@ struct _AudioStream
time_t last_packet_time; time_t last_packet_time;
EchoLimiterType el_type; /*use echo limiter: two MSVolume, measured input level controlling local output level*/ EchoLimiterType el_type; /*use echo limiter: two MSVolume, measured input level controlling local output level*/
OrtpEvQueue *evq; OrtpEvQueue *evq;
MSAudioBitrateController *rc; MSBitrateController *rc;
MSQualityIndicator *qi; MSQualityIndicator *qi;
time_t start_time; time_t start_time;
bool_t play_dtmfs; bool_t play_dtmfs;
......
...@@ -60,6 +60,7 @@ libmediastreamer_la_SOURCES= mscommon.c $(GITVERSION_FILE) \ ...@@ -60,6 +60,7 @@ libmediastreamer_la_SOURCES= mscommon.c $(GITVERSION_FILE) \
l16.c \ l16.c \
audioconference.c \ audioconference.c \
bitratedriver.c \ bitratedriver.c \
qosanalyzer.c \
bitratecontrol.c bitratecontrol.c
#dummy c++ file to force libtool to use c++ linking (because of msdscap-mingw.cc) #dummy c++ file to force libtool to use c++ linking (because of msdscap-mingw.cc)
......
...@@ -70,7 +70,7 @@ void audio_stream_free(AudioStream *stream) ...@@ -70,7 +70,7 @@ void audio_stream_free(AudioStream *stream)
if (stream->read_resampler!=NULL) ms_filter_destroy(stream->read_resampler); if (stream->read_resampler!=NULL) ms_filter_destroy(stream->read_resampler);
if (stream->write_resampler!=NULL) ms_filter_destroy(stream->write_resampler); if (stream->write_resampler!=NULL) ms_filter_destroy(stream->write_resampler);
if (stream->dtmfgen_rtp!=NULL) ms_filter_destroy(stream->dtmfgen_rtp); if (stream->dtmfgen_rtp!=NULL) ms_filter_destroy(stream->dtmfgen_rtp);
if (stream->rc) ms_audio_bitrate_controller_destroy(stream->rc); if (stream->rc) ms_bitrate_controller_destroy(stream->rc);
if (stream->qi) ms_quality_indicator_destroy(stream->qi); if (stream->qi) ms_quality_indicator_destroy(stream->qi);
ms_free(stream); ms_free(stream);
} }
...@@ -176,7 +176,7 @@ static void audio_stream_process_rtcp(AudioStream *stream, mblk_t *m){ ...@@ -176,7 +176,7 @@ static void audio_stream_process_rtcp(AudioStream *stream, mblk_t *m){
flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0); flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0);
ms_message("audio_stream_process_rtcp: interarrival jitter=%u , " ms_message("audio_stream_process_rtcp: interarrival jitter=%u , "
"lost packets percentage since last report=%f, round trip time=%f seconds",ij,flost,rt); "lost packets percentage since last report=%f, round trip time=%f seconds",ij,flost,rt);
if (stream->rc) ms_audio_bitrate_controller_process_rtcp(stream->rc,m); if (stream->rc) ms_bitrate_controller_process_rtcp(stream->rc,m);
if (stream->qi) ms_quality_indicator_update_from_feedback(stream->qi,m); if (stream->qi) ms_quality_indicator_update_from_feedback(stream->qi,m);
} }
}while(rtcp_next_packet(m)); }while(rtcp_next_packet(m));
......
...@@ -40,35 +40,38 @@ const char *state_name(enum state_t st){ ...@@ -40,35 +40,38 @@ const char *state_name(enum state_t st){
return "bad state"; return "bad state";
} }
struct _MSAudioBitrateController{ struct _MSBitrateController{
QosAnalyser analyzer; MSQosAnalyser *analyser;
RtpSession *session; MSBitrateDriver *driver;
MSFilter *encoder;
enum state_t state; enum state_t state;
int stable_count; int stable_count;
int probing_up_count; int probing_up_count;
}; };
MSAudioBitrateController *ms_audio_bitrate_controller_new(RtpSession *session, MSFilter *encoder, unsigned int flags){ MSBitrateController *ms_bitrate_controller_new(MSQosAnalyser *qosanalyser, MSBitrateDriver *driver){
MSAudioBitrateController *rc=ms_new0(MSAudioBitrateController,1); MSBitrateController *obj=ms_new0(MSBitrateController,1);
obj->analyser=ms_qos_analyser_ref(qosanalyser);
ms_qos_analyser_init(&rc->analyser,session); obj->driver=ms_bitrate_driver_ref(driver);
return rc; return obj;
}
static int execute_action(MSBitrateController *obj, const MSRateControlAction *action){
return ms_bitrate_driver_execute_action(obj->driver,action);
} }
static void state_machine(MSAudioBitrateController *obj){ static void state_machine(MSBitrateController *obj){
action_t action; MSRateControlAction action;
switch(obj->state){ switch(obj->state){
case Stable: case Stable:
obj->stable_count++; obj->stable_count++;
case Init: case Init:
ms_qos_analyser_suggest_action(&obj->analyser,&action); ms_qos_analyser_suggest_action(obj->analyser,&action);
if (action.type!=DoNothing){ if (action.type!=MSRateControlActionDoNothing){
execute_action(obj,&action); execute_action(obj,&action);
obj->state=Probing; obj->state=Probing;
}else if (obj->stable_count>=5){ }else if (obj->stable_count>=5){
action.type=IncreaseQuality; action.type=MSRateControlActionIncreaseQuality;
execute_action(obj,&action); execute_action(obj,&action);
obj->state=ProbingUp; obj->state=ProbingUp;
obj->probing_up_count=0; obj->probing_up_count=0;
...@@ -76,11 +79,11 @@ static void state_machine(MSAudioBitrateController *obj){ ...@@ -76,11 +79,11 @@ static void state_machine(MSAudioBitrateController *obj){
break; break;
case Probing: case Probing:
obj->stable_count=0; obj->stable_count=0;
if (has_improved(obj)){ if (ms_qos_analyser_has_improved(obj->analyser)){
obj->state=Stable; obj->state=Stable;
}else{ }else{
ms_qos_analyser_suggest_action(&obj->analyser,&action); ms_qos_analyser_suggest_action(obj->analyser,&action);
if (action.type!=DoNothing){ if (action.type!=MSRateControlActionDoNothing){
execute_action(obj,&action); execute_action(obj,&action);
} }
} }
...@@ -88,14 +91,14 @@ static void state_machine(MSAudioBitrateController *obj){ ...@@ -88,14 +91,14 @@ static void state_machine(MSAudioBitrateController *obj){
case ProbingUp: case ProbingUp:
obj->stable_count=0; obj->stable_count=0;
obj->probing_up_count++; obj->probing_up_count++;
ms_qos_analyser_suggest_action(&obj->analyser,&action); ms_qos_analyser_suggest_action(obj->analyser,&action);
if (action.type!=DoNothing){ if (action.type!=MSRateControlActionDoNothing){
execute_action(obj,&action); execute_action(obj,&action);
obj->state=Probing; obj->state=Probing;
}else{ }else{
/*continue with slow ramp up*/ /*continue with slow ramp up*/
if (obj->probing_up_count==2){ if (obj->probing_up_count==2){
action.type=IncreaseQuality; action.type=MSRateControlActionIncreaseQuality;
if (execute_action(obj,&action)==-1){ if (execute_action(obj,&action)==-1){
/* we reached the maximum*/ /* we reached the maximum*/
obj->state=Init; obj->state=Init;
...@@ -107,19 +110,26 @@ static void state_machine(MSAudioBitrateController *obj){ ...@@ -107,19 +110,26 @@ static void state_machine(MSAudioBitrateController *obj){
default: default:
break; break;
} }
ms_message("AudioBitrateController: current state is %s",state_name(obj->state)); ms_message("MSBitrateController: current state is %s",state_name(obj->state));
} }
void ms_audio_bitrate_controller_process_rtcp(MSAudioBitrateController *obj, mblk_t *rtcp){ void ms_bitrate_controller_process_rtcp(MSBitrateController *obj, mblk_t *rtcp){
if (ms_qos_analyser_process_rtcp(&obj->analyser,rtcp)){ if (ms_qos_analyser_process_rtcp(obj->analyser,rtcp)){
state_machine(obj); state_machine(obj);
} }
} }
void ms_audio_bitrate_controller_destroy(MSAudioBitrateController *obj){ void ms_bitrate_controller_destroy(MSBitrateController *obj){
ms_qos_analyser_unref(obj->analyser);
ms_bitrate_driver_unref(obj->driver);
ms_free(obj); ms_free(obj);
} }
MSBitrateController *ms_audio_bitrate_controller_new(RtpSession *session, MSFilter *encoder, unsigned int flags){
return ms_bitrate_controller_new(
ms_simple_qos_analyser_new(session),
ms_audio_bitrate_driver_new(encoder));
}
...@@ -22,16 +22,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -22,16 +22,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/bitratecontrol.h" #include "mediastreamer2/bitratecontrol.h"
void ms_bitrate_driver_execute_action(MSBitrateDriver *obj, const MSRateControlAction *action){ static const int max_ptime=100;
int ms_bitrate_driver_execute_action(MSBitrateDriver *obj, const MSRateControlAction *action){
if (obj->desc->execute_action) if (obj->desc->execute_action)
obj->desc->execute_action(obj,action); return obj->desc->execute_action(obj,action);
else ms_error("Driver does not implement execute_action"); else ms_error("Driver does not implement execute_action");
return -1;
}
MSBitrateDriver * ms_bitrate_driver_ref(MSBitrateDriver *obj){
obj->refcnt++;
return obj;
} }
void ms_bitrate_driver_destroy(MSBitrateDriver *obj){ void ms_bitrate_driver_unref(MSBitrateDriver *obj){
if (obj->desc->uninit) obj->refcnt--;
obj->desc->uninit(obj); if (obj->refcnt<=0){
ms_free(obj); if (obj->desc->uninit)
obj->desc->uninit(obj);
ms_free(obj);
}
} }
struct _MSAudioBitrateDriver{ struct _MSAudioBitrateDriver{
...@@ -63,9 +74,9 @@ static int inc_ptime(MSAudioBitrateDriver *obj){ ...@@ -63,9 +74,9 @@ static int inc_ptime(MSAudioBitrateDriver *obj){
return 0; return 0;
} }
static int audio_bitrate_driver_execute_action(MSBitrateDriver *objbase, MSRateControlAction *action){ static int audio_bitrate_driver_execute_action(MSBitrateDriver *objbase, const MSRateControlAction *action){
MSAudioBitrateDriver *obj=(MSBitrateDriver*)objbase; MSAudioBitrateDriver *obj=(MSAudioBitrateDriver*)objbase;
ms_message("MSAudioBitrateDriver: executing action of type %s, value=%i",action_type_name(action->type),action->value); ms_message("MSAudioBitrateDriver: executing action of type %s, value=%i",ms_rate_control_action_type_name(action->type),action->value);
if (action->type==MSRateControlActionDecreaseBitrate){ if (action->type==MSRateControlActionDecreaseBitrate){
/*reducing bitrate of the codec actually doesn't work very well (not enough). Increasing ptime is much more efficient*/ /*reducing bitrate of the codec actually doesn't work very well (not enough). Increasing ptime is much more efficient*/
if (inc_ptime(obj)==-1){ if (inc_ptime(obj)==-1){
...@@ -128,8 +139,9 @@ static MSBitrateDriverDesc audio_bitrate_driver={ ...@@ -128,8 +139,9 @@ static MSBitrateDriverDesc audio_bitrate_driver={
MSBitrateDriver *ms_audio_bitrate_driver_new(MSFilter *encoder){ MSBitrateDriver *ms_audio_bitrate_driver_new(MSFilter *encoder){
MSAudioBitrateDriver *obj=ms_new0(MSAudioBitrateDriver,1); MSAudioBitrateDriver *obj=ms_new0(MSAudioBitrateDriver,1);
obj->parent.desc=&audio_bitrate_driver;
obj->encoder=encoder; obj->encoder=encoder;
obj->cur_ptime=obj->min_ptime=20; obj->cur_ptime=obj->min_ptime=20;
obj->cur_bitrate=obj->nom_bitrate=0; obj->cur_bitrate=obj->nom_bitrate=0;
return obj; return (MSBitrateDriver*)obj;
} }
...@@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Analyses a received RTCP packet. * Analyses a received RTCP packet.
* Returns TRUE is relevant information has been found in the rtcp message, FALSE otherwise. * Returns TRUE is relevant information has been found in the rtcp message, FALSE otherwise.
**/ **/
bool_t ms_qos_analyzer_process_rtcp(MSQosAnalyzer *obj,mblk_t *msg){ bool_t ms_qos_analyser_process_rtcp(MSQosAnalyser *obj,mblk_t *msg){
if (obj->desc->process_rtcp){ if (obj->desc->process_rtcp){
return obj->desc->process_rtcp(obj,msg); return obj->desc->process_rtcp(obj,msg);
} }
...@@ -34,25 +34,33 @@ bool_t ms_qos_analyzer_process_rtcp(MSQosAnalyzer *obj,mblk_t *msg){ ...@@ -34,25 +34,33 @@ bool_t ms_qos_analyzer_process_rtcp(MSQosAnalyzer *obj,mblk_t *msg){
return FALSE; return FALSE;
} }
void ms_qos_analyser_suggest_action(MSQosAnalyzer *obj, MSRateControlActionType *action){ void ms_qos_analyser_suggest_action(MSQosAnalyser *obj, MSRateControlAction *action){
if (obj->desc->suggest_action){ if (obj->desc->suggest_action){
obj->desc->suggest_action(obj,action); obj->desc->suggest_action(obj,action);
} }
return; return;
} }
bool_t ms_qos_analyzer_has_improved(MSQosAnalyzer *obj){ bool_t ms_qos_analyser_has_improved(MSQosAnalyser *obj){
if (obj->desc->has_improved){ if (obj->desc->has_improved){
return obj->desc->has_improved(obj,action); return obj->desc->has_improved(obj);
} }
ms_error("Unimplemented has_improved() call."); ms_error("Unimplemented has_improved() call.");
return TRUE; return TRUE;
} }
void ms_qos_analyzer_destroy(MSQosAnalyzer *obj){ MSQosAnalyser *ms_qos_analyser_ref(MSQosAnalyser *obj){
if (obj->desc->uninit) obj->refcnt++;
obj->desc->uninit(obj); return obj;
ms_free(obj); }
void ms_qos_analyser_unref(MSQosAnalyser *obj){
obj->refcnt--;
if (obj->refcnt<=0){
if (obj->desc->uninit)
obj->desc->uninit(obj);
ms_free(obj);
}
} }
#define STATS_HISTORY 3 #define STATS_HISTORY 3
...@@ -60,7 +68,6 @@ void ms_qos_analyzer_destroy(MSQosAnalyzer *obj){ ...@@ -60,7 +68,6 @@ void ms_qos_analyzer_destroy(MSQosAnalyzer *obj){
static const float unacceptable_loss_rate=20; static const float unacceptable_loss_rate=20;
static const int big_jitter=20; /*ms */ static const int big_jitter=20; /*ms */
static const float significant_delay=0.2; /*seconds*/ static const float significant_delay=0.2; /*seconds*/
static const int max_ptime=100;
typedef struct rtpstats{ typedef struct rtpstats{
...@@ -71,7 +78,7 @@ typedef struct rtpstats{ ...@@ -71,7 +78,7 @@ typedef struct rtpstats{
}rtpstats_t; }rtpstats_t;
static const char *action_type_name(enum MSRateControlActionType t){ const char *ms_rate_control_action_type_name(MSRateControlActionType t){
switch(t){ switch(t){
case MSRateControlActionDoNothing: case MSRateControlActionDoNothing:
return "DoNothing"; return "DoNothing";
...@@ -87,14 +94,14 @@ static const char *action_type_name(enum MSRateControlActionType t){ ...@@ -87,14 +94,14 @@ static const char *action_type_name(enum MSRateControlActionType t){
typedef struct _MSSimpleQosAnalyser{ typedef struct _MSSimpleQosAnalyser{
MSQosAnalyzer parent; MSQosAnalyser parent;
RtpSession *session; RtpSession *session;
int clockrate; int clockrate;
rtpstats_t stats[STATS_HISTORY]; rtpstats_t stats[STATS_HISTORY];
int curindex; int curindex;
bool_t rt_prop_doubled; bool_t rt_prop_doubled;
bool_t pad[3]; bool_t pad[3];
}MSQosAnalyser; }MSSimpleQosAnalyser;
...@@ -109,7 +116,7 @@ static bool_t rt_prop_doubled(rtpstats_t *cur,rtpstats_t *prev){ ...@@ -109,7 +116,7 @@ static bool_t rt_prop_doubled(rtpstats_t *cur,rtpstats_t *prev){
return FALSE; return FALSE;
} }
static bool_t rt_prop_increased(MSSimpleQosAnalyzer *obj){ static bool_t rt_prop_increased(MSSimpleQosAnalyser *obj){
rtpstats_t *cur=&obj->stats[obj->curindex % STATS_HISTORY]; rtpstats_t *cur=&obj->stats[obj->curindex % STATS_HISTORY];
rtpstats_t *prev=&obj->stats[(STATS_HISTORY+obj->curindex-1) % STATS_HISTORY]; rtpstats_t *prev=&obj->stats[(STATS_HISTORY+obj->curindex-1) % STATS_HISTORY];
...@@ -122,7 +129,7 @@ static bool_t rt_prop_increased(MSSimpleQosAnalyzer *obj){ ...@@ -122,7 +129,7 @@ static bool_t rt_prop_increased(MSSimpleQosAnalyzer *obj){
static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp){ static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp){
MSSimpleQosAnalyzer *obj=(MSSimpleQosAnalyzer*)objbase; MSSimpleQosAnalyser *obj=(MSSimpleQosAnalyser*)objbase;
rtpstats_t *cur; rtpstats_t *cur;
const report_block_t *rb=NULL; const report_block_t *rb=NULL;
if (rtcp_is_SR(rtcp)){ if (rtcp_is_SR(rtcp)){
...@@ -130,7 +137,7 @@ static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp) ...@@ -130,7 +137,7 @@ static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp)
}else if (rtcp_is_RR(rtcp)){ }else if (rtcp_is_RR(rtcp)){
rb=rtcp_RR_get_report_block(rtcp,0); rb=rtcp_RR_get_report_block(rtcp,0);
} }
if (rb){ if (rb && report_block_get_ssrc(rb)==rtp_session_get_send_ssrc(obj->session)){
obj->curindex++; obj->curindex++;
cur=&obj->stats[obj->curindex % STATS_HISTORY]; cur=&obj->stats[obj->curindex % STATS_HISTORY];
...@@ -150,8 +157,8 @@ static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp) ...@@ -150,8 +157,8 @@ static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp)
return rb!=NULL; return rb!=NULL;
} }
static void simple_analyser_suggest_action(MSQosAnalyser *objbase, MSRateControlActionType *action){ static void simple_analyser_suggest_action(MSQosAnalyser *objbase, MSRateControlAction *action){
MSSimpleQosAnalyzer *obj=(MSSimpleQosAnalyzer*)objbase; MSSimpleQosAnalyser *obj=(MSSimpleQosAnalyser*)objbase;
rtpstats_t *cur=&obj->stats[obj->curindex % STATS_HISTORY]; rtpstats_t *cur=&obj->stats[obj->curindex % STATS_HISTORY];
/*big losses and big jitter */ /*big losses and big jitter */
if (cur->lost_percentage>=unacceptable_loss_rate && cur->int_jitter>=big_jitter){ if (cur->lost_percentage>=unacceptable_loss_rate && cur->int_jitter>=big_jitter){
...@@ -173,7 +180,7 @@ static void simple_analyser_suggest_action(MSQosAnalyser *objbase, MSRateControl ...@@ -173,7 +180,7 @@ static void simple_analyser_suggest_action(MSQosAnalyser *objbase, MSRateControl
} }
static bool_t simple_analyser_has_improved(MSQosAnalyser *objbase){ static bool_t simple_analyser_has_improved(MSQosAnalyser *objbase){
MSSimpleQosAnalyzer *obj=(MSSimpleQosAnalyzer*)objbase; MSSimpleQosAnalyser *obj=(MSSimpleQosAnalyser*)objbase;
rtpstats_t *cur=&obj->stats[obj->curindex % STATS_HISTORY]; rtpstats_t *cur=&obj->stats[obj->curindex % STATS_HISTORY];
rtpstats_t *prev=&obj->stats[(STATS_HISTORY+obj->curindex-1) % STATS_HISTORY]; rtpstats_t *prev=&obj->stats[(STATS_HISTORY+obj->curindex-1) % STATS_HISTORY];
...@@ -194,16 +201,16 @@ end: ...@@ -194,16 +201,16 @@ end:
return FALSE; return FALSE;
} }
static MSQosAnalyzerDesc simple_analyzer_desc={ static MSQosAnalyserDesc simple_analyser_desc={
simple_analyser_process_rtcp, simple_analyser_process_rtcp,
simple_analyser_suggest_action, simple_analyser_suggest_action,
simple_analyzer_has_improved simple_analyser_has_improved
}; };
MSQosAnalyzer * ms_simple_qos_analyser_new(RtpSession *session){ MSQosAnalyser * ms_simple_qos_analyser_new(RtpSession *session){
MSSimpleQosAnalyzer *obj=ms_new0(MSSimpleQosAnalyzer,1); MSSimpleQosAnalyser *obj=ms_new0(MSSimpleQosAnalyser,1);
obj->session=session; obj->session=session;
obj->parent.desc=&simple_analyzer_desc; obj->parent.desc=&simple_analyser_desc;
return (MSQosAnalyzer*)obj; return (MSQosAnalyser*)obj;
} }
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