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);
}
Beispiel #2
0
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]);
		}
	}
}