static void stateful_analyzer_suggest_action(MSQosAnalyzer *objbase, MSRateControlAction *action){ MSStatefulQosAnalyzer *obj=(MSStatefulQosAnalyzer*)objbase; float curbw = obj->latest ? obj->latest->bandwidth : 0.f; float bw = compute_available_bw(obj); /*try a burst every 50 seconds (10 RTCP packets)*/ if (obj->curindex % 10 == 0){ ms_debug("MSQosStatefulAnalyzer[%p]: try burst!", obj); obj->burst_state = MSStatefulQosAnalyzerBurstEnable; } /*test a min burst to avoid overestimation of available bandwidth*/ else if (obj->curindex % 10 == 2 || obj->curindex % 10 == 3){ ms_debug("MSQosStatefulAnalyzer[%p]: try minimal burst!", obj); bw *= .33; } /*no bandwidth estimation computed*/ if (bw <= 0 || curbw <= 0){ action->type=MSRateControlActionDoNothing; action->value=0; }else if (bw > curbw){ action->type=MSRateControlActionIncreaseQuality; action->value=MAX(0, 100. * (bw / curbw - 1)); }else{ action->type=MSRateControlActionDecreaseBitrate; action->value=MAX(10, -100. * (bw / curbw - 1)); } ms_debug("MSQosStatefulAnalyzer[%p]: %s of value %d", obj, ms_rate_control_action_type_name(action->type), action->value); }
static void stateful_analyzer_suggest_action(MSQosAnalyzer *objbase, MSRateControlAction *action){ MSStatefulQosAnalyzer *obj=(MSStatefulQosAnalyzer*)objbase; float curbw = 0; float bw = 0; rtcpstatspoint_t* greatest_pt = NULL; /*if this is the first measure, there is not enough reliable data to use; we assume loss rate is due to non congestionned network. This is mainly useful in the case loss rate is high (>30%), to reduce quality even before the second RTCP report which can be really used. */ if (obj->curindex==1){ if (obj->network_loss_rate!=0.f){ action->type=MSRateControlActionDecreaseBitrate; action->value=obj->network_loss_rate; } }else { curbw = obj->latest ? obj->latest->bandwidth : 0.f; bw = compute_available_bw(obj); greatest_pt = ms_list_size(obj->rtcpstatspoint) ? (rtcpstatspoint_t*)ms_list_nth_data(obj->rtcpstatspoint, ms_list_size(obj->rtcpstatspoint)-1) : NULL; /*try a burst every 50 seconds (10 RTCP packets)*/ if (obj->curindex % 10 == 6){ ms_message("MSStatefulQosAnalyzer[%p]: try burst!", obj); obj->burst_state = MSStatefulQosAnalyzerBurstEnable; } /*test a min burst to avoid overestimation of available bandwidth but only if there is some loss*/ else if (greatest_pt!=NULL && greatest_pt->loss_percent>1 && (obj->curindex % 10 == 2 || obj->curindex % 10 == 3)){ ms_message("MSStatefulQosAnalyzer[%p]: try minimal burst!", obj); bw *= .33; } /*no bandwidth estimation computed*/ if (bw <= 0 || curbw <= 0){ action->type=MSRateControlActionDoNothing; action->value=0; }else if (bw > curbw){ action->type=MSRateControlActionIncreaseQuality; action->value=MAX(0, 100. * (bw / curbw - 1)); }else{ action->type=MSRateControlActionDecreaseBitrate; action->value=MAX(10, -100. * (bw / curbw - 1)); } } ms_message("MSStatefulQosAnalyzer[%p]: %s of value %d", obj, ms_rate_control_action_type_name(action->type), action->value); if (objbase->on_action_suggested!=NULL){ int i; char *data[4]; int datac = sizeof(data) / sizeof(data[0]); data[0]=ms_strdup("%loss rtt_ms cur_bw"); data[1]=ms_strdup_printf("%d %d %d" , obj->latest?(int)obj->latest->loss_percent:0 , obj->latest?(int)obj->latest->rtt:0 , obj->latest?(int)obj->latest->bandwidth:0 ); data[2]=ms_strdup("action_type action_value est_bw"); data[3]=ms_strdup_printf("%s %d %d" , ms_rate_control_action_type_name(action->type) , action->value , (int)bw ); objbase->on_action_suggested(objbase->on_action_suggested_user_pointer, datac, (const char**)data); for (i=0;i<datac;++i){ ms_free(data[i]); } } }