1 /*
2 mediastreamer2 library - modular sound and video processing and streaming
3
4 * Copyright (C) 2011 Belledonne Communications, Grenoble, France
5
6 Author: Simon Morlat <simon.morlat@linphone.org>
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23 #include "mediastreamer2/bitratecontrol.h"
24
25 #include <bctoolbox/defs.h>
26
27 static const int probing_up_interval=10;
28
29 enum state_t{
30 Init,
31 Probing,
32 Stable,
33 ProbingUp
34 };
35
state_name(enum state_t st)36 const char *state_name(enum state_t st){
37 switch(st){
38 case Init: return "Init";
39 case Probing: return "Probing";
40 case Stable: return "Stable";
41 case ProbingUp: return "ProbingUp";
42 }
43 return "bad state";
44 }
45
46 struct _MSBitrateController{
47 MSQosAnalyzer *analyzer;
48 MSBitrateDriver *driver;
49 enum state_t state;
50 int stable_count;
51 int probing_up_count;
52
53 };
54
ms_bitrate_controller_new(MSQosAnalyzer * qosanalyzer,MSBitrateDriver * driver)55 MSBitrateController *ms_bitrate_controller_new(MSQosAnalyzer *qosanalyzer, MSBitrateDriver *driver){
56 MSBitrateController *obj=ms_new0(MSBitrateController,1);
57 obj->analyzer=ms_qos_analyzer_ref(qosanalyzer);
58 obj->driver=ms_bitrate_driver_ref(driver);
59 return obj;
60 }
61
execute_action(MSBitrateController * obj,const MSRateControlAction * action)62 static int execute_action(MSBitrateController *obj, const MSRateControlAction *action){
63 return ms_bitrate_driver_execute_action(obj->driver,action);
64 }
65
state_machine(MSBitrateController * obj)66 static void state_machine(MSBitrateController *obj){
67 MSRateControlAction action = {0};
68 switch(obj->state){
69 case Stable:
70 obj->stable_count++;
71 BCTBX_NO_BREAK; /*intentionally no break*/
72 case Init:
73 ms_qos_analyzer_suggest_action(obj->analyzer,&action);
74 if (action.type!=MSRateControlActionDoNothing){
75 execute_action(obj,&action);
76 obj->state=Probing;
77 }else if (obj->stable_count>=probing_up_interval){
78 action.type=MSRateControlActionIncreaseQuality;
79 action.value=10;
80 execute_action(obj,&action);
81 obj->state=ProbingUp;
82 obj->probing_up_count=0;
83 }
84 break;
85 case Probing:
86 obj->stable_count=0;
87 if (ms_qos_analyzer_has_improved(obj->analyzer)){
88 obj->state=Stable;
89 }else{
90 ms_qos_analyzer_suggest_action(obj->analyzer,&action);
91 if (action.type!=MSRateControlActionDoNothing){
92 execute_action(obj,&action);
93 }
94 }
95 break;
96 case ProbingUp:
97 obj->stable_count=0;
98 obj->probing_up_count++;
99 ms_qos_analyzer_suggest_action(obj->analyzer,&action);
100 if (action.type!=MSRateControlActionDoNothing){
101 execute_action(obj,&action);
102 obj->state=Probing;
103 }else{
104 /*continue with slow ramp up*/
105 if (obj->probing_up_count==2){
106 action.type=MSRateControlActionIncreaseQuality;
107 action.value=10;
108 if (execute_action(obj,&action)==-1){
109 /* we reached the maximum*/
110 obj->state=Init;
111 }
112 obj->probing_up_count=0;
113 }
114 }
115 break;
116 default:
117 break;
118 }
119 ms_message("MSBitrateController: current state is %s",state_name(obj->state));
120 }
121
122
123
ms_bitrate_controller_process_rtcp(MSBitrateController * obj,mblk_t * rtcp)124 void ms_bitrate_controller_process_rtcp(MSBitrateController *obj, mblk_t *rtcp){
125 if (ms_qos_analyzer_process_rtcp(obj->analyzer,rtcp)){
126 state_machine(obj);
127 }
128 }
129
ms_bitrate_controller_update(MSBitrateController * obj)130 void ms_bitrate_controller_update(MSBitrateController *obj){
131 ms_qos_analyzer_update(obj->analyzer);
132 }
133
ms_bitrate_controller_get_qos_analyzer(MSBitrateController * obj)134 MSQosAnalyzer * ms_bitrate_controller_get_qos_analyzer(MSBitrateController *obj){
135 return obj->analyzer;
136 }
137
ms_bitrate_controller_destroy(MSBitrateController * obj)138 void ms_bitrate_controller_destroy(MSBitrateController *obj){
139 ms_qos_analyzer_unref(obj->analyzer);
140 ms_bitrate_driver_unref(obj->driver);
141 ms_free(obj);
142 }
143
ms_audio_bitrate_controller_new(RtpSession * session,MSFilter * encoder,unsigned int flags)144 MSBitrateController *ms_audio_bitrate_controller_new(RtpSession *session, MSFilter *encoder, unsigned int flags){
145 return ms_bitrate_controller_new(
146 ms_simple_qos_analyzer_new(session),
147 ms_audio_bitrate_driver_new(session, encoder));
148 }
149
ms_av_bitrate_controller_new(RtpSession * asession,MSFilter * aenc,RtpSession * vsession,MSFilter * venc)150 MSBitrateController *ms_av_bitrate_controller_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc){
151 return ms_bitrate_controller_new(
152 ms_simple_qos_analyzer_new(vsession),
153 ms_av_bitrate_driver_new(asession, aenc, vsession, venc));
154 }
155
ms_bandwidth_bitrate_controller_new(RtpSession * asession,MSFilter * aenc,RtpSession * vsession,MSFilter * venc)156 MSBitrateController *ms_bandwidth_bitrate_controller_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc){
157 return ms_bitrate_controller_new(
158 ms_stateful_qos_analyzer_new(vsession?vsession:asession),
159 ms_bandwidth_bitrate_driver_new(asession, aenc, vsession, venc));
160 }
161