~ubuntu-branches/ubuntu/trusty/linphone/trusty

« back to all changes in this revision

Viewing changes to mediastreamer2/src/bitratedriver.c

  • Committer: Package Import Robot
  • Author(s): Luk Claes
  • Date: 2013-09-11 19:08:43 UTC
  • mfrom: (1.1.19) (16.1.12 sid)
  • Revision ID: package-import@ubuntu.com-20130911190843-fkydjxsdvy1fmx24
Tags: 3.6.1-2.1
* Non-maintainer upload.
* Apply Sebastian Ramacher's patch to fix FTBFS (Closes: #720668).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
 
 */
22
 
 
23
 
#include "mediastreamer2/bitratecontrol.h"
24
 
 
25
 
static const int max_ptime=100;
26
 
 
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");
31
 
        return -1;
32
 
}
33
 
 
34
 
MSBitrateDriver * ms_bitrate_driver_ref(MSBitrateDriver *obj){
35
 
        obj->refcnt++;
36
 
        return obj;
37
 
}
38
 
 
39
 
void ms_bitrate_driver_unref(MSBitrateDriver *obj){
40
 
        obj->refcnt--;
41
 
        if (obj->refcnt<=0){
42
 
                if (obj->desc->uninit)
43
 
                        obj->desc->uninit(obj);
44
 
                ms_free(obj);
45
 
        }
46
 
}
47
 
 
48
 
struct _MSAudioBitrateDriver{
49
 
        MSBitrateDriver parent;
50
 
        MSFilter *encoder;
51
 
        int min_ptime;
52
 
        int nom_bitrate;
53
 
        int cur_ptime;
54
 
        int cur_bitrate;
55
 
};
56
 
 
57
 
typedef struct _MSAudioBitrateDriver MSAudioBitrateDriver;
58
 
 
59
 
static void apply_ptime(MSAudioBitrateDriver *obj){
60
 
        char tmp[64];
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);
65
 
}
66
 
 
67
 
static int inc_ptime(MSAudioBitrateDriver *obj){
68
 
        if (obj->cur_ptime>=max_ptime){
69
 
                ms_message("AudioBitrateController: maximum ptime reached");
70
 
                return -1;
71
 
        }
72
 
        obj->cur_ptime+=obj->min_ptime;
73
 
        apply_ptime(obj);
74
 
        return 0;
75
 
}
76
 
 
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){
84
 
                                int cur_br=0;
85
 
                                int new_br;
86
 
 
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);
90
 
                                        }       
91
 
                                        obj->cur_bitrate=obj->nom_bitrate;
92
 
                                }
93
 
                                /*if max ptime is reached, then try to reduce the codec bitrate if possible */
94
 
                                
95
 
                                if (ms_filter_call_method(obj->encoder,MS_FILTER_GET_BITRATE,&cur_br)!=0){
96
 
                                        ms_message("AudioBitrateController: GET_BITRATE failed");
97
 
                                        return 0;
98
 
                                }
99
 
                                new_br=cur_br-((cur_br*action->value)/100);
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");
104
 
                                        inc_ptime(obj);
105
 
                                        return 0;
106
 
                                }
107
 
                                new_br=0;
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;
111
 
                        }
112
 
                }
113
 
        }else if (action->type==MSRateControlActionDecreasePacketRate){
114
 
                inc_ptime(obj);
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;
123
 
                        apply_ptime(obj);
124
 
                }else return -1;
125
 
        }
126
 
        return 0;
127
 
}
128
 
 
129
 
static void audio_bitrate_driver_uninit(MSBitrateDriver *objbase){
130
 
        //MSAudioBitrateDriver *obj=(MSBitrateDriver*)objbase;
131
 
        
132
 
}
133
 
 
134
 
static MSBitrateDriverDesc audio_bitrate_driver={
135
 
        audio_bitrate_driver_execute_action,
136
 
        audio_bitrate_driver_uninit
137
 
};
138
 
 
139
 
 
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;
147
 
}
148
 
 
149
 
static const int min_video_bitrate=64000;
150
 
static const float increase_ramp=1.1;
151
 
 
152
 
typedef struct _MSAVBitrateDriver{
153
 
        MSBitrateDriver parent;
154
 
        MSBitrateDriver *audio_driver;
155
 
        MSFilter *venc;
156
 
        int nom_bitrate;
157
 
        int cur_bitrate;
158
 
}MSAVBitrateDriver;
159
 
 
160
 
static int dec_video_bitrate(MSAVBitrateDriver *obj, const MSRateControlAction *action){
161
 
        int new_br;
162
 
        
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;
168
 
        }
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;
173
 
}
174
 
 
175
 
static int inc_video_bitrate(MSAVBitrateDriver *obj, const MSRateControlAction *action){
176
 
        int newbr;
177
 
        int ret=0;
178
 
        
179
 
        newbr=(float)obj->cur_bitrate*(1.0+((float)action->value/100.0));
180
 
        if (newbr>obj->nom_bitrate){
181
 
                newbr=obj->nom_bitrate;
182
 
                ret=-1;
183
 
        }
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);
187
 
        return ret;
188
 
}
189
 
 
190
 
static int av_driver_execute_action(MSBitrateDriver *objbase, const MSRateControlAction *action){
191
 
        MSAVBitrateDriver *obj=(MSAVBitrateDriver*)objbase;
192
 
        int ret=0;
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.");
197
 
                        return -1;
198
 
                }
199
 
        }
200
 
        
201
 
        switch(action->type){
202
 
                case MSRateControlActionDecreaseBitrate:
203
 
                        ret=dec_video_bitrate(obj,action);
204
 
                break;
205
 
                case MSRateControlActionDecreasePacketRate:
206
 
                        if (obj->audio_driver){
207
 
                                ret=ms_bitrate_driver_execute_action(obj->audio_driver,action);
208
 
                        }
209
 
                break;
210
 
                case MSRateControlActionIncreaseQuality:
211
 
                        ret=inc_video_bitrate(obj,action);
212
 
                break;
213
 
                case MSRateControlActionDoNothing:
214
 
                break;
215
 
        }
216
 
        return ret;
217
 
}
218
 
 
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);
223
 
        
224
 
}
225
 
 
226
 
static MSBitrateDriverDesc av_bitrate_driver={
227
 
        av_driver_execute_action,
228
 
        av_bitrate_driver_uninit
229
 
};
230
 
 
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;
235
 
        obj->venc=venc;
236
 
        
237
 
        return (MSBitrateDriver*)obj;
238
 
}
239
 
 
240