2
mediastreamer2 library - modular sound and video processing and streaming
4
* Copyright (C) 2011 Belledonne Communications, Grenoble, France
6
Author: Simon Morlat <simon.morlat@linphone.org>
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
#include "mediastreamer2/bitratecontrol.h"
25
static const int max_ptime=100;
27
int ms_bitrate_driver_execute_action(MSBitrateDriver *obj, const MSRateControlAction *action){
28
if (obj->desc->execute_action)
29
return obj->desc->execute_action(obj,action);
30
else ms_error("Driver does not implement execute_action");
34
MSBitrateDriver * ms_bitrate_driver_ref(MSBitrateDriver *obj){
39
void ms_bitrate_driver_unref(MSBitrateDriver *obj){
42
if (obj->desc->uninit)
43
obj->desc->uninit(obj);
48
struct _MSAudioBitrateDriver{
49
MSBitrateDriver parent;
57
typedef struct _MSAudioBitrateDriver MSAudioBitrateDriver;
59
static void apply_ptime(MSAudioBitrateDriver *obj){
61
snprintf(tmp,sizeof(tmp),"ptime=%i",obj->cur_ptime);
62
if (ms_filter_call_method(obj->encoder,MS_FILTER_ADD_FMTP,tmp)!=0){
63
ms_message("AudioBitrateController: failed ptime command.");
64
}else ms_message("AudioBitrateController: ptime changed to %i",obj->cur_ptime);
67
static int inc_ptime(MSAudioBitrateDriver *obj){
68
if (obj->cur_ptime>=max_ptime){
69
ms_message("AudioBitrateController: maximum ptime reached");
72
obj->cur_ptime+=obj->min_ptime;
77
static int audio_bitrate_driver_execute_action(MSBitrateDriver *objbase, const MSRateControlAction *action){
78
MSAudioBitrateDriver *obj=(MSAudioBitrateDriver*)objbase;
79
ms_message("MSAudioBitrateDriver: executing action of type %s, value=%i",ms_rate_control_action_type_name(action->type),action->value);
80
if (action->type==MSRateControlActionDecreaseBitrate){
81
/*reducing bitrate of the codec actually doesn't work very well (not enough). Increasing ptime is much more efficient*/
82
if (inc_ptime(obj)==-1){
83
if (obj->nom_bitrate>0){
87
if (obj->nom_bitrate==0){
88
if (ms_filter_call_method(obj->encoder,MS_FILTER_GET_BITRATE,&obj->nom_bitrate)!=0){
89
ms_message("MSAudioBitrateDriver: Encoder has nominal bitrate %i",obj->nom_bitrate);
91
obj->cur_bitrate=obj->nom_bitrate;
93
/*if max ptime is reached, then try to reduce the codec bitrate if possible */
95
if (ms_filter_call_method(obj->encoder,MS_FILTER_GET_BITRATE,&cur_br)!=0){
96
ms_message("AudioBitrateController: GET_BITRATE failed");
99
new_br=cur_br-((cur_br*action->value)/100);
101
ms_message("MSAudioBitrateDriver: Attempting to reduce audio bitrate to %i",new_br);
102
if (ms_filter_call_method(obj->encoder,MS_FILTER_SET_BITRATE,&new_br)!=0){
103
ms_message("MSAudioBitrateDriver: SET_BITRATE failed, incrementing ptime");
108
ms_filter_call_method(obj->encoder,MS_FILTER_GET_BITRATE,&new_br);
109
ms_message("MSAudioBitrateDriver: bitrate actually set to %i",new_br);
110
obj->cur_bitrate=new_br;
113
}else if (action->type==MSRateControlActionDecreasePacketRate){
115
}else if (action->type==MSRateControlActionIncreaseQuality){
116
if (obj->cur_bitrate<obj->nom_bitrate){
117
ms_message("MSAudioBitrateDriver: increasing bitrate of codec");
118
if (ms_filter_call_method(obj->encoder,MS_FILTER_SET_BITRATE,&obj->nom_bitrate)!=0){
119
ms_message("MSAudioBitrateDriver: could not restore nominal codec bitrate (%i)",obj->nom_bitrate);
120
}else obj->cur_bitrate=obj->nom_bitrate;
121
}else if (obj->cur_ptime>obj->min_ptime){
122
obj->cur_ptime-=obj->min_ptime;
129
static void audio_bitrate_driver_uninit(MSBitrateDriver *objbase){
130
//MSAudioBitrateDriver *obj=(MSBitrateDriver*)objbase;
134
static MSBitrateDriverDesc audio_bitrate_driver={
135
audio_bitrate_driver_execute_action,
136
audio_bitrate_driver_uninit
140
MSBitrateDriver *ms_audio_bitrate_driver_new(MSFilter *encoder){
141
MSAudioBitrateDriver *obj=ms_new0(MSAudioBitrateDriver,1);
142
obj->parent.desc=&audio_bitrate_driver;
143
obj->encoder=encoder;
144
obj->cur_ptime=obj->min_ptime=20;
145
obj->cur_bitrate=obj->nom_bitrate=0;
146
return (MSBitrateDriver*)obj;
149
static const int min_video_bitrate=64000;
150
static const float increase_ramp=1.1;
152
typedef struct _MSAVBitrateDriver{
153
MSBitrateDriver parent;
154
MSBitrateDriver *audio_driver;
160
static int dec_video_bitrate(MSAVBitrateDriver *obj, const MSRateControlAction *action){
163
ms_filter_call_method(obj->venc,MS_FILTER_GET_BITRATE,&obj->cur_bitrate);
164
new_br=((float)obj->cur_bitrate)*(100.0-(float)action->value)/100.0;
165
if (new_br<min_video_bitrate){
166
ms_message("MSAVBitrateDriver: reaching low bound.");
167
new_br=min_video_bitrate;
169
ms_message("MSAVBitrateDriver: targeting %i bps for video encoder.",new_br);
170
ms_filter_call_method(obj->venc,MS_FILTER_SET_BITRATE,&new_br);
171
obj->cur_bitrate=new_br;
172
return new_br==min_video_bitrate ? -1 : 0;
175
static int inc_video_bitrate(MSAVBitrateDriver *obj, const MSRateControlAction *action){
179
newbr=(float)obj->cur_bitrate*(1.0+((float)action->value/100.0));
180
if (newbr>obj->nom_bitrate){
181
newbr=obj->nom_bitrate;
184
obj->cur_bitrate=newbr;
185
ms_message("MSAVBitrateDriver: increasing bitrate to %i bps for video encoder.",obj->cur_bitrate);
186
ms_filter_call_method(obj->venc,MS_FILTER_SET_BITRATE,&obj->cur_bitrate);
190
static int av_driver_execute_action(MSBitrateDriver *objbase, const MSRateControlAction *action){
191
MSAVBitrateDriver *obj=(MSAVBitrateDriver*)objbase;
193
if (obj->nom_bitrate==0){
194
ms_filter_call_method(obj->venc,MS_FILTER_GET_BITRATE,&obj->nom_bitrate);
195
if (obj->nom_bitrate==0){
196
ms_warning("MSAVBitrateDriver: Not doing adaptive rate control on video encoder, it does not seem to support that.");
201
switch(action->type){
202
case MSRateControlActionDecreaseBitrate:
203
ret=dec_video_bitrate(obj,action);
205
case MSRateControlActionDecreasePacketRate:
206
if (obj->audio_driver){
207
ret=ms_bitrate_driver_execute_action(obj->audio_driver,action);
210
case MSRateControlActionIncreaseQuality:
211
ret=inc_video_bitrate(obj,action);
213
case MSRateControlActionDoNothing:
219
static void av_bitrate_driver_uninit(MSBitrateDriver *objbase){
220
MSAVBitrateDriver *obj=(MSAVBitrateDriver*)objbase;
221
if (obj->audio_driver)
222
ms_bitrate_driver_unref(obj->audio_driver);
226
static MSBitrateDriverDesc av_bitrate_driver={
227
av_driver_execute_action,
228
av_bitrate_driver_uninit
231
MSBitrateDriver *ms_av_bitrate_driver_new(MSFilter *aenc, MSFilter *venc){
232
MSAVBitrateDriver *obj=ms_new0(MSAVBitrateDriver,1);
233
obj->parent.desc=&av_bitrate_driver;
234
obj->audio_driver=(aenc!=NULL) ? ms_bitrate_driver_ref(ms_audio_bitrate_driver_new(aenc)) : NULL;
237
return (MSBitrateDriver*)obj;