first try to handle congestion state and some test refactoring

parent 31e2602a
......@@ -86,7 +86,7 @@ struct _MSQosAnalyserDesc{
};
/**
* A MSQosAnalyzer is responsible to analyze RTCP feedback and suggest actions on bitrate or packet rate accordingly.
* A MSQosAnalyser is responsible to analyze RTCP feedback and suggest actions on bitrate or packet rate accordingly.
* This is an abstract interface.
**/
struct _MSQosAnalyser{
......@@ -94,15 +94,19 @@ 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
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_is_network_stable(const 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);
/**
* The simple qos analyzer is an implementation of MSQosAnalyser that performs analysis for single stream.
* The simple qos analyser is an implementation of MSQosAnalyser that performs analysis for single stream.
**/
MSQosAnalyser * ms_simple_qos_analyser_new(RtpSession *session);
......
......@@ -288,11 +288,11 @@ MS2_PUBLIC int audio_stream_start_with_files (AudioStream * stream, RtpProfile *
/**
* Starts an audio stream from/to local wav files or soundcards.
*
*
* This method starts the processing of the audio stream, that is playing from wav file or soundcard, voice processing, encoding,
* sending through RTP, receiving from RTP, decoding, voice processing and wav file recording or soundcard playback.
*
*
*
*
* @param stream an AudioStream previously created with audio_stream_new().
* @param prof a RtpProfile containing all PayloadType possible during the audio session.
* @param rem_rtp_ip remote IP address where to send the encoded audio.
......@@ -362,16 +362,16 @@ MS2_PUBLIC AudioStream *audio_stream_new_with_sessions(const MSMediaStreamSessio
MS2_PUBLIC uint32_t audio_stream_get_features(AudioStream *st);
MS2_PUBLIC void audio_stream_set_features(AudioStream *st, uint32_t features);
MS2_PUBLIC void audio_stream_prepare_sound(AudioStream *st, MSSndCard *playcard, MSSndCard *captcard);
MS2_PUBLIC void audio_stream_unprepare_sound(AudioStream *st);
MS2_PUBLIC bool_t audio_stream_started(AudioStream *stream);
/**
* Starts an audio stream from local soundcards.
*
*
* This method starts the processing of the audio stream, that is capture from soundcard, voice processing, encoding,
* sending through RTP, receiving from RTP, decoding, voice processing and soundcard playback.
*
*
* @param stream an AudioStream previously created with audio_stream_new().
* @param prof a RtpProfile containing all PayloadType possible during the audio session.
* @param remip remote IP address where to send the encoded audio.
......
......@@ -45,7 +45,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef MS_MINIMAL_MTU
/*this is used for determining the minimum size of recv buffers for RTP packets
Keep 1500 for maximum interoparibility*/
#define MS_MINIMAL_MTU 1500
#define MS_MINIMAL_MTU 1500
#endif
......@@ -81,12 +81,12 @@ static void media_stream_change_decoder(MediaStream *stream, int payload) {
RtpSession *session = stream->sessions.rtp_session;
RtpProfile *prof = rtp_session_get_profile(session);
PayloadType *pt = rtp_profile_get_payload(prof, payload);
if (stream->decoder == NULL){
ms_message("media_stream_change_decoder(): ignored, no decoder.");
return;
}
if (pt != NULL){
MSFilter *dec;
......@@ -226,7 +226,7 @@ void media_stream_free(MediaStream *stream) {
if (stream->decoder != NULL) ms_filter_destroy(stream->decoder);
if (stream->voidsink != NULL) ms_filter_destroy(stream->voidsink);
if (stream->qi) ms_quality_indicator_destroy(stream->qi);
}
void media_stream_set_rtcp_information(MediaStream *stream, const char *cname, const char *tool) {
......@@ -262,7 +262,7 @@ static int check_srtp_session_created(MediaStream *stream){
err_status_t err;
srtp_t session;
RtpTransport *rtp=NULL,*rtcp=NULL;
err = ortp_srtp_create(&session, NULL);
if (err != 0) {
ms_error("Failed to create srtp session (%d)", err);
......@@ -284,9 +284,9 @@ static bool_t add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, c
err_status_t err;
unsigned b64_key_length = strlen(b64_key);
ssrc_t ssrc_conf;
memset(&policy,0,sizeof(policy));
switch(suite){
case MS_AES_128_SHA1_32:
crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
......@@ -330,22 +330,22 @@ static bool_t add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, c
}
if (!inbound)
policy.allow_repeat_tx=1; /*necessary for telephone-events*/
/*ssrc_conf.type=inbound ? ssrc_any_inbound : ssrc_specific;*/
ssrc_conf.type=ssrc_specific;
ssrc_conf.value=ssrc;
policy.ssrc = ssrc_conf;
policy.key = key;
policy.next = NULL;
err = srtp_add_stream(srtp, &policy);
if (err != err_status_ok) {
ortp_error("Failed to add stream to srtp session (%d)", err);
ortp_free(key);
return -1;
}
ortp_free(key);
return 0;
}
......@@ -371,7 +371,7 @@ bool_t media_stream_srtp_supported(void){
}
int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, const char* key){
if (!media_stream_srtp_supported()) {
ms_error("ortp srtp support disabled in oRTP or mediastreamer2");
return -1;
......@@ -380,14 +380,14 @@ int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, con
{
uint32_t ssrc,send_ssrc;
bool_t updated=FALSE;
if (check_srtp_session_created(stream)==-1)
return -1;
/*check if a previous key was configured, in which case remove it*/
send_ssrc=rtp_session_get_send_ssrc(stream->sessions.rtp_session);
ssrc=find_other_ssrc(stream->sessions.srtp_session,htonl(send_ssrc));
/*careful: remove_stream takes the SSRC in network byte order...*/
if (ortp_srtp_remove_stream(stream->sessions.srtp_session,ssrc)==0)
updated=TRUE;
......@@ -401,20 +401,20 @@ int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, con
}
int media_stream_set_srtp_send_key(MediaStream *stream, MSCryptoSuite suite, const char* key){
if (!media_stream_srtp_supported()) {
ms_error("ortp srtp support disabled in oRTP or mediastreamer2");
return -1;
}
#ifdef ORTP_HAVE_SRTP
{
uint32_t ssrc;
bool_t updated=FALSE;
if (check_srtp_session_created(stream)==-1)
return -1;
/*check if a previous key was configured, in which case remove it*/
ssrc=rtp_session_get_send_ssrc(stream->sessions.rtp_session);
if (ssrc!=0){
......@@ -465,7 +465,7 @@ void mediastream_payload_type_changed(RtpSession *session, unsigned long data) {
void media_stream_iterate(MediaStream *stream){
time_t curtime=ms_time(NULL);
if (stream->ice_check_list) ice_check_list_process(stream->ice_check_list,stream->sessions.rtp_session);
/*we choose to update the quality indicator as much as possible, since local statistics can be computed realtime. */
if (stream->state==MSStreamStarted){
......@@ -483,7 +483,7 @@ void media_stream_iterate(MediaStream *stream){
OrtpEventType evt=ortp_event_get_type(ev);
if (evt==ORTP_EVENT_RTCP_PACKET_RECEIVED){
mblk_t *m=ortp_event_get_data(ev)->packet;
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":""));
ms_message("%s_stream_iterate[%p]: receiving [%p] RTCP %s%s",media_stream_type_str(stream),stream,m,(rtcp_is_SR(m)?"SR":""),(rtcp_is_RR(m)?"RR":""));
stream->process_rtcp(stream,m);
}else if (evt==ORTP_EVENT_RTCP_PACKET_EMITTED){
ms_message("%s_stream_iterate[%p]: local statistics available\n\tLocal's current jitter buffer size:%f ms",
......@@ -493,7 +493,7 @@ void media_stream_iterate(MediaStream *stream){
} else if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED) {
OrtpEventData *evd=ortp_event_get_data(ev);
stream->sessions.is_secured=evd->info.zrtp_stream_encrypted;
ms_message("%s stream [%p] is %s ",media_stream_type_str(stream) , stream, stream->sessions.is_secured ? "encrypted" : "not encrypted");
ms_message("%s_stream_iterate[%p]: is %s ",media_stream_type_str(stream) , stream, stream->sessions.is_secured ? "encrypted" : "not encrypted");
}
ortp_event_destroy(ev);
}
......
......@@ -24,40 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <math.h>
/**
* Compute the linear interpolation y = m * x + b for a given set of points.
* m is the line slope, b the y-intercept value and x_inter the x-intrecept value
* Returns 1 if x intersection could not be calculated, 0 otherwise
**/
// static int linear_regression(int n, const double x[], const double y[], double* m, double* b, double* x_inter)
// {
// int i;
// double x_sum = 0.;
// double y_sum = 0.;
// double x_square_sum = 0.;
// double x_y_sum = 0.;
// for (i = 0; i < n; i++) {
// x_sum += x[i];
// y_sum += y[i];
// x_y_sum += x[i] * y[i];
// x_square_sum += (x[i]) * (x[i]);
// }
// x_sum /= n;
// y_sum /= n;
// *m = (x_y_sum - x_sum * y_sum * n) /
// (x_square_sum - x_sum * x_sum * n);
// *b = (y_sum - *m * x_sum);
// if (fabs(*m) > 0.000001f) {
// *x_inter = - *b / *m;
// return 0;
// }
// return 1;
// }
/**
* Analyses a received RTCP packet.
* Returns TRUE is relevant information has been found in the rtcp message, FALSE otherwise.
......@@ -138,14 +104,14 @@ typedef struct _MSSimpleQosAnalyser{
bool_t rt_prop_doubled;
bool_t pad[3];
double points[150][2];
bool_t stable_network;
double points[150][3];
uint8_t network_state;
}MSSimpleQosAnalyser;
static bool_t rt_prop_doubled(rtpstats_t *cur,rtpstats_t *prev){
//ms_message("AudioBitrateController: cur=%f, prev=%f",cur->rt_prop,prev->rt_prop);
/*ms_message("AudioBitrateController: cur=%f, prev=%f",cur->rt_prop,prev->rt_prop);*/
if (cur->rt_prop>=significant_delay && prev->rt_prop>0){
if (cur->rt_prop>=(prev->rt_prop*2.0)){
/*propagation doubled since last report */
......@@ -166,7 +132,6 @@ static bool_t rt_prop_increased(MSSimpleQosAnalyser *obj){
return FALSE;
}
static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp){
MSSimpleQosAnalyser *obj=(MSSimpleQosAnalyser*)objbase;
rtpstats_t *cur;
......@@ -191,8 +156,10 @@ static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp)
cur->lost_percentage=100.0*(float)report_block_get_fraction_lost(rb)/256.0;
cur->int_jitter=1000.0*(float)report_block_get_interarrival_jitter(rb)/(float)obj->clockrate;
cur->rt_prop=rtp_session_get_round_trip_propagation(obj->session);
obj->points[obj->curindex-1][0]=rtp_session_get_send_bandwidth(obj->session)/1000.0;
obj->points[obj->curindex-1][1]=(float)report_block_get_fraction_lost(rb)/256.0;
obj->points[obj->curindex-1][1]=cur->lost_percentage;
obj->points[obj->curindex-1][2]=cur->rt_prop;
ms_message("MSQosAnalyser: lost_percentage=%f, int_jitter=%f ms, rt_prop=%f sec, send_bw=%f",cur->lost_percentage,cur->int_jitter,cur->rt_prop,obj->points[obj->curindex][0]);
if (obj->curindex>2) printf("one more %d: %f %f\n", obj->curindex-1, obj->points[obj->curindex-1][0], obj->points[obj->curindex-1][1]);
......@@ -202,74 +169,100 @@ static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp)
static void compute_available_bw(MSSimpleQosAnalyser *obj){
int i;
double x_sum = 0.;
double y_sum = 0.;
double x_mean = 0.;
double y_mean = 0.;
double x_square_sum = 0.;
double x_y_sum = 0.;
int last = obj->curindex - 1;
int f = last > 15 ? last - 13 : 2; //always skip the 2 first ones
int n = (last - f + 1);
double mean_bw = 0.;
double mean_diff = 0.;
int x_min_ind = f;
int x_max_ind = f;
bool_t lossy_network = FALSE;
double diff, m, b;
uint8_t previous_state = obj->network_state;
obj->network_state = MS_QOS_ANALYSER_NETWORK_FINE;
if (n <= 1) {
printf("Estimated BW is %f kbit/s\n", obj->points[0][0] * obj->points[0][1]);
return;
}
int count = n;//(last - f) * (last - f + 1) / 2;
double mean_bw = 0.;
double avg_dist = 0.;
int x_min_ind = f;
int x_max_ind = f;
for (i = f; i <= last; i++) {
double x = obj->points[i][0];
double y = obj->points[i][1];
if (x < obj->points[x_min_ind][0]) x_min_ind = i;
if (x > obj->points[x_max_ind][0]) x_max_ind = i;
double mul = 1;// (i - f + 1);
// printf("\tadding (%f;%f) of weight %f\n", x, y, mul);
x_sum += x * mul;
y_sum += y * mul;
x_y_sum += x * y * mul * mul;
x_square_sum += x * x * mul * mul;
x_mean += x;
y_mean += y;
x_y_sum += x * y;
x_square_sum += x * x;
mean_bw += x * (1 - y);
}
x_sum /= count;
y_sum /= count;
mean_bw /= count;
x_mean /= n;
y_mean /= n;
mean_bw /= n;
printf("\tEstimated BW by avg is %f kbit/s\n", mean_bw);
printf("sum=%f xmin=%d xmax=%d\n", x_sum, x_min_ind, x_max_ind);
double diff = (obj->points[x_max_ind][0] - obj->points[x_min_ind][0]) / x_sum;
printf("sum=%f xmin=%d xmax=%d\n", x_mean, x_min_ind, x_max_ind);
diff = (obj->points[x_max_ind][0] - obj->points[x_min_ind][0]) / x_mean;
m = (x_y_sum - x_mean * y_mean * n) /
(x_square_sum - x_mean * x_mean * n);
double m = (x_y_sum - x_sum * y_sum * count) /
(x_square_sum - x_sum * x_sum * count);
b = (y_mean - m * x_mean);
double b = (y_sum - m * x_sum);
for (i = f; i <= last; i++) {
double x = obj->points[i][0];
double y = obj->points[i][1];
avg_dist += fabs(m * x + b - y);
mean_diff += fabs(m * x + b - y);
}
avg_dist /= count;
mean_diff /= n;
bool_t lossy_network = avg_dist > .1;
// to compute estimated BW, we need a minimum sample size
/*to compute estimated BW, we need a minimum x-axis interval size*/
if (diff > 0.05) {
double avail_bw = (fabs(m) > 0.0001f) ? - b / m : mean_bw;
printf("\tfor line is %f kbit/s\n", avail_bw);
printf("\t\ty=%f x + %f\n", m, b);
double avail_bw = (fabs(m) > 0.0001f) ? -b/m : mean_bw;
printf("\tfor line is %f kbit/s:\ty=%f x + %f\n", avail_bw, m, b);
lossy_network |= (m < .03f && b > 0.05);
if (!lossy_network && (m>.03f||b>0.05)){
obj->network_state = MS_QOS_ANALYSER_NETWORK_CONGESTED;
}
} else {
printf("\tinsufficient difference between BW min and BW max: %f\n", diff);
lossy_network |= (y_mean > 0.05);
}
if (lossy_network) {
/*since congestion may loss a high count of packets, stay in congested network while
this is not a bit more stable*/
if (previous_state == MS_QOS_ANALYSER_NETWORK_CONGESTED) {
obj->network_state = MS_QOS_ANALYSER_NETWORK_CONGESTED;
} else {
obj->network_state = MS_QOS_ANALYSER_NETWORK_UNSTABLE;
}
/*another hint for a bad network: packets drop mean difference is high*/
} else if (mean_diff > .1) {
double rtt = obj->points[last][2];
obj->network_state = (rtt > .5) ? MS_QOS_ANALYSER_NETWORK_CONGESTED : MS_QOS_ANALYSER_NETWORK_UNSTABLE;
}
printf("\tavg_dist=%f\n", avg_dist);
printf("\t\tI think it is a %s network\n", lossy_network ? "LOSSY/UNSTABLE" : "stable");
obj->stable_network = !lossy_network;
if (obj->network_state == MS_QOS_ANALYSER_NETWORK_CONGESTED)
printf("\t\tI think it is a %s network\n", "C-O-N-G-E-S-T-E-D");
else if (obj->network_state == MS_QOS_ANALYSER_NETWORK_UNSTABLE)
printf("\t\tI think it is a %s network\n", "UNSTABLE");
else
printf("\t\tI think it is a %s network\n", "stable");
}
static void simple_analyser_suggest_action(MSQosAnalyser *objbase, MSRateControlAction *action){
......@@ -315,9 +308,9 @@ end:
return FALSE;
}
bool_t ms_qos_analyser_is_network_stable(const MSQosAnalyser *objbase){
uint32_t ms_qos_analyser_get_network_state(const MSQosAnalyser *objbase){
MSSimpleQosAnalyser *obj=(MSSimpleQosAnalyser*)objbase;
return obj->stable_network;
return obj->network_state;
}
static MSQosAnalyserDesc simple_analyser_desc={
......@@ -330,7 +323,6 @@ MSQosAnalyser * ms_simple_qos_analyser_new(RtpSession *session){
MSSimpleQosAnalyser *obj=ms_new0(MSSimpleQosAnalyser,1);
obj->session=session;
obj->parent.desc=&simple_analyser_desc;
obj->stable_network=TRUE;
return (MSQosAnalyser*)obj;
}
......@@ -153,6 +153,8 @@ static void basic_audio_stream() {
rtp_profile_set_payload (profile,0,&payload_type_pcmu8000);
/*recorder should be initialized before sender to avoid missing the first
emitted packets*/
CU_ASSERT_EQUAL(audio_stream_start_full(margaux
, profile
, MARIELLE_IP
......
......@@ -74,7 +74,7 @@ typedef struct _video_stream_manager_t {
struct {
float loss;
float rtt;
bool_t stable_network;
uint8_t network_state;
} latest_stats;
} video_stream_manager_t ;
static video_stream_manager_t * video_stream_manager_new() {
......@@ -82,7 +82,6 @@ static video_stream_manager_t * video_stream_manager_new() {
mgr->local_rtp= (rand() % ((2^16)-1024) + 1024) & ~0x1;
mgr->local_rtcp=mgr->local_rtp+1;
mgr->stream = video_stream_new (mgr->local_rtp, mgr->local_rtcp,FALSE);
mgr->latest_stats.stable_network = TRUE;
return mgr;
}
......@@ -119,7 +118,7 @@ static void handle_queue_events(video_stream_manager_t * stream_mgr, OrtpEvQueue
while (NULL != (ev=ortp_ev_queue_get(evq))){
OrtpEventType evt=ortp_event_get_type(ev);
OrtpEventData *evd=ortp_event_get_data(ev);
/*linphone_call_stats_fill(&call->stats[stream_index],ms,ev);*/
if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED || evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
const report_block_t *rb=NULL;
if (rtcp_is_SR(evd->packet)){
......@@ -127,21 +126,27 @@ static void handle_queue_events(video_stream_manager_t * stream_mgr, OrtpEvQueue
}else if (rtcp_is_RR(evd->packet)){
rb=rtcp_RR_get_report_block(evd->packet,0);
}
printf("%s RTCP thing\n", (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) ? "RECEIVED" : "EMITTED");
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.stable_network=ms_qos_analyser_is_network_stable(ms_bitrate_controller_get_qos_analyser(stream_mgr->stream->ms.rc));
printf("loss=%f\n",stream_mgr->latest_stats.loss);
printf("RTT=%f\n",stream_mgr->latest_stats.rtt);
printf("stable_network=%d\n",stream_mgr->latest_stats.stable_network);
if (rb) {
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\n",
(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);
}
}
static void start_adaptive_video_stream(video_stream_manager_t * marielle, video_stream_manager_t * margaux, int payload, int initial_bitrate,int target_bw, float loss_rate, int latency, int max_recv_rtcp_packet) {
static void start_adaptive_video_stream(video_stream_manager_t * marielle, video_stream_manager_t * margaux,
int payload, int initial_bitrate,int target_bw, float loss_rate, int latency, int max_recv_rtcp_packet) {
MSWebCam * marielle_webcam = ms_web_cam_manager_get_default_cam (ms_web_cam_manager_get());
MSWebCam * margaux_webcam = ms_web_cam_manager_get_cam(ms_web_cam_manager_get(), "StaticImage: Static picture");
......@@ -181,17 +186,27 @@ static void start_adaptive_video_stream(video_stream_manager_t * marielle, video
&margaux->stream->ms, media_stream_get_down_bw(&margaux->stream->ms)/1000, media_stream_get_up_bw(&margaux->stream->ms)/1000);
}
ms_usleep(100000);
}
rtp_session_unregister_event_queue(marielle->stream->ms.sessions.rtp_session,evq);
ortp_ev_queue_destroy(evq);
}
#define INIT() \
marielle = video_stream_manager_new(); \
margaux = video_stream_manager_new();
#define DEINIT() \
video_stream_manager_delete(marielle); \
video_stream_manager_delete(margaux);
static void lossy_network() {
video_stream_manager_t * marielle, * margaux;
/*verify that some webcam is supported*/
bool_t supported = (ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get()) != NULL);
video_stream_manager_t * marielle = video_stream_manager_new();
video_stream_manager_t * margaux = video_stream_manager_new();
if( supported ) {
float bw_usage;
//for test purpose only
int loss_rate = getenv("GPP_LOSS") ? atoi(getenv("GPP_LOSS")) : 0;
int max_bw = getenv("GPP_MAXBW") ? atoi(getenv("GPP_MAXBW")) * 1000: 0;
int latency = getenv("GPP_LAG") ? atoi(getenv("GPP_LAG")): 0;
......@@ -200,27 +215,35 @@ static void lossy_network() {
printf("max_bw=%d(GPP_MAXBW)\n", max_bw);
printf("latency=%d(GPP_LAG)\n", latency);
INIT();
start_adaptive_video_stream(marielle, margaux, VP8_PAYLOAD_TYPE, 300000, max_bw, loss_rate, latency, 20);
float marielle_send_bw=media_stream_get_up_bw(&marielle->stream->ms);
bw_usage=(max_bw > 0) ? marielle_send_bw/max_bw : 0;
bw_usage=(max_bw > 0) ? marielle_send_bw/max_bw : 1;
ms_message("marielle sent bw=[%f], target was [%d] bw_usage [%f]",marielle_send_bw,max_bw,bw_usage);
DEINIT();
CU_ASSERT_IN_RANGE(bw_usage, .9f, 1.f);
}
video_stream_manager_delete(marielle);
video_stream_manager_delete(margaux);
}
static void stability_network_detection() {
video_stream_manager_t * marielle = video_stream_manager_new();
video_stream_manager_t * margaux = video_stream_manager_new();
video_stream_manager_t * marielle, * margaux;
INIT();
start_adaptive_video_stream(marielle, margaux, VP8_PAYLOAD_TYPE, 300000, 0, 0, 500, 10);
CU_ASSERT_TRUE(marielle->latest_stats.stable_network);
video_stream_manager_delete(marielle);
video_stream_manager_delete(margaux);
CU_ASSERT_EQUAL(marielle->latest_stats.network_state, MS_QOS_ANALYSER_NETWORK_FINE);
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);
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);
DEINIT();
}
static test_t tests[] = {
......
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