bitratecontrol.c 3.73 KB
Newer Older
1 2 3 4 5
/*
mediastreamer2 library - modular sound and video processing and streaming

 * Copyright (C) 2011  Belledonne Communications, Grenoble, France

6 7
	 Author: Simon Morlat <simon.morlat@linphone.org>

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include "mediastreamer2/bitratecontrol.h"


enum state_t{
	Init,
	Probing,
	Stable,
	ProbingUp
};

const char *state_name(enum state_t st){
	switch(st){
		case Init: return "Init";
		case Probing: return "Probing";
		case Stable: return "Stable";
		case ProbingUp: return "ProbingUp";
	}
	return "bad state";
}

43 44 45
struct _MSBitrateController{
	MSQosAnalyser *analyser;
	MSBitrateDriver *driver;
46 47
	enum state_t state;
	int stable_count;
48
	int probing_up_count;
49
	
50 51
};

52 53 54 55 56 57 58 59 60
MSBitrateController *ms_bitrate_controller_new(MSQosAnalyser *qosanalyser, MSBitrateDriver *driver){
	MSBitrateController *obj=ms_new0(MSBitrateController,1);
	obj->analyser=ms_qos_analyser_ref(qosanalyser);
	obj->driver=ms_bitrate_driver_ref(driver);
	return obj;
}

static int execute_action(MSBitrateController *obj, const MSRateControlAction *action){
	return ms_bitrate_driver_execute_action(obj->driver,action);
61 62
}

63 64
static void state_machine(MSBitrateController *obj){
	MSRateControlAction action;
65 66 67 68
	switch(obj->state){
		case Stable:
			obj->stable_count++;
		case Init:
69 70
			ms_qos_analyser_suggest_action(obj->analyser,&action);
			if (action.type!=MSRateControlActionDoNothing){
71 72 73
				execute_action(obj,&action);
				obj->state=Probing;
			}else if (obj->stable_count>=5){
74
				action.type=MSRateControlActionIncreaseQuality;
75 76
				execute_action(obj,&action);
				obj->state=ProbingUp;
77
				obj->probing_up_count=0;
78 79 80 81
			}
		break;
		case Probing:
			obj->stable_count=0;
82
			if (ms_qos_analyser_has_improved(obj->analyser)){
83 84
				obj->state=Stable;
			}else{
85 86
				ms_qos_analyser_suggest_action(obj->analyser,&action);
				if (action.type!=MSRateControlActionDoNothing){
87 88 89 90 91 92
					execute_action(obj,&action);
				}
			}
		break;
		case ProbingUp:
			obj->stable_count=0;
93
			obj->probing_up_count++;
94 95
			ms_qos_analyser_suggest_action(obj->analyser,&action);
			if (action.type!=MSRateControlActionDoNothing){
96 97 98
				execute_action(obj,&action);
				obj->state=Probing;
			}else{
99 100
				/*continue with slow ramp up*/
				if (obj->probing_up_count==2){
101
					action.type=MSRateControlActionIncreaseQuality;
102 103 104 105 106
					if (execute_action(obj,&action)==-1){
						/* we reached the maximum*/
						obj->state=Init;
					}
					obj->probing_up_count=0;
107 108 109 110 111 112
				}
			}
		break;
		default:
		break;
	}
113
	ms_message("MSBitrateController: current state is %s",state_name(obj->state));
114 115 116 117
}



118 119
void ms_bitrate_controller_process_rtcp(MSBitrateController *obj, mblk_t *rtcp){
	if (ms_qos_analyser_process_rtcp(obj->analyser,rtcp)){
120 121 122 123
		state_machine(obj);
	}
}

124 125 126
void ms_bitrate_controller_destroy(MSBitrateController *obj){
	ms_qos_analyser_unref(obj->analyser);
	ms_bitrate_driver_unref(obj->driver);
127 128 129
	ms_free(obj);
}

130 131 132 133 134
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));
}
135