1 /*
2 mediastreamer2 library - modular sound and video processing and streaming
3 Copyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 */
19 
20 
21 #ifdef HAVE_CONFIG_H
22 #include "mediastreamer-config.h"
23 #endif
24 
25 #include "mediastreamer2/mediastream.h"
26 #include "mediastreamer2/dtmfgen.h"
27 #include "mediastreamer2/mssndcard.h"
28 #include "mediastreamer2/msrtp.h"
29 #include "mediastreamer2/msfileplayer.h"
30 #include "mediastreamer2/msfilerec.h"
31 #include "mediastreamer2/msvolume.h"
32 #include "mediastreamer2/msequalizer.h"
33 #include "mediastreamer2/mstee.h"
34 #include "mediastreamer2/msaudiomixer.h"
35 #include "mediastreamer2/mscodecutils.h"
36 #include "mediastreamer2/msitc.h"
37 #include "mediastreamer2/msvaddtx.h"
38 #include "mediastreamer2/msgenericplc.h"
39 #include "mediastreamer2/mseventqueue.h"
40 #include "private.h"
41 
42 #ifdef __ANDROID__
43 #include "mediastreamer2/devices.h"
44 #endif
45 
46 #if __APPLE__
47 #include "TargetConditionals.h"
48 #endif
49 
50 #include <sys/types.h>
51 
52 #ifndef _WIN32
53 	#include <sys/socket.h>
54 	#include <netdb.h>
55 #endif
56 
57 static void configure_av_recorder(AudioStream *stream);
58 static void configure_decoder(AudioStream *stream, PayloadType *pt, int sample_rate, int nchannels);
59 static void audio_stream_configure_resampler(AudioStream *st, MSFilter *resampler,MSFilter *from, MSFilter *to);
60 static void audio_stream_set_rtp_output_gain_db(AudioStream *stream, float gain_db);
61 
audio_stream_free(AudioStream * stream)62 static void audio_stream_free(AudioStream *stream) {
63 	media_stream_free(&stream->ms);
64 	if (stream->soundread!=NULL) ms_filter_destroy(stream->soundread);
65 	if (stream->soundwrite!=NULL) ms_filter_destroy(stream->soundwrite);
66 	if (stream->dtmfgen!=NULL) ms_filter_destroy(stream->dtmfgen);
67 	if (stream->flowcontrol != NULL) ms_filter_destroy(stream->flowcontrol);
68 	if (stream->plc!=NULL)	ms_filter_destroy(stream->plc);
69 	if (stream->ec!=NULL)	ms_filter_destroy(stream->ec);
70 	if (stream->volrecv!=NULL) ms_filter_destroy(stream->volrecv);
71 	if (stream->volsend!=NULL) ms_filter_destroy(stream->volsend);
72 	if (stream->mic_equalizer) ms_filter_destroy(stream->mic_equalizer);
73 	if (stream->spk_equalizer) ms_filter_destroy(stream->spk_equalizer);
74 	if (stream->read_decoder != NULL) ms_filter_destroy(stream->read_decoder);
75 	if (stream->write_encoder != NULL) ms_filter_destroy(stream->write_encoder);
76 	if (stream->read_resampler!=NULL) ms_filter_destroy(stream->read_resampler);
77 	if (stream->write_resampler!=NULL) ms_filter_destroy(stream->write_resampler);
78 	if (stream->dtmfgen_rtp!=NULL) ms_filter_destroy(stream->dtmfgen_rtp);
79 	if (stream->dummy) ms_filter_destroy(stream->dummy);
80 	if (stream->recv_tee) ms_filter_destroy(stream->recv_tee);
81 	if (stream->recorder) ms_filter_destroy(stream->recorder);
82 	if (stream->recorder_mixer) ms_filter_destroy(stream->recorder_mixer);
83 	if (stream->local_mixer) ms_filter_destroy(stream->local_mixer);
84 	if (stream->local_player) ms_filter_destroy(stream->local_player);
85 	if (stream->local_player_resampler) ms_filter_destroy(stream->local_player_resampler);
86 	if (stream->av_recorder.encoder) ms_filter_destroy(stream->av_recorder.encoder);
87 	if (stream->av_recorder.recorder) ms_filter_destroy(stream->av_recorder.recorder);
88 	if (stream->av_recorder.resampler) ms_filter_destroy(stream->av_recorder.resampler);
89 	if (stream->av_recorder.video_input) ms_filter_destroy(stream->av_recorder.video_input);
90 	if (stream->vaddtx) ms_filter_destroy(stream->vaddtx);
91 	if (stream->outbound_mixer) ms_filter_destroy(stream->outbound_mixer);
92 	if (stream->recorder_file) ms_free(stream->recorder_file);
93 	if (stream->rtp_io_session) rtp_session_destroy(stream->rtp_io_session);
94 
95 	ms_free(stream);
96 }
97 
98 static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'};
99 
on_dtmf_received(RtpSession * s,uint32_t dtmf,void * user_data)100 static void on_dtmf_received(RtpSession *s, uint32_t dtmf, void *user_data)
101 {
102 	AudioStream *stream=(AudioStream*)user_data;
103 	if (dtmf>15){
104 		ms_warning("Unsupported telephone-event type.");
105 		return;
106 	}
107 	ms_message("Receiving dtmf %c.",dtmf_tab[dtmf]);
108 	if (stream->dtmfgen!=NULL && stream->play_dtmfs){
109 		ms_filter_call_method(stream->dtmfgen,MS_DTMF_GEN_PUT,&dtmf_tab[dtmf]);
110 	}
111 }
112 
113 /**
114  * This function must be called from the MSTicker thread:
115  * it replaces one filter by another one.
116  * This is a dirty hack that works anyway.
117  * It would be interesting to have something that does the job
118  * more easily within the MSTicker API.
119  * return TRUE if the decoder was changed, FALSE otherwise.
120  */
audio_stream_payload_type_changed(RtpSession * session,void * data)121 static bool_t audio_stream_payload_type_changed(RtpSession *session, void *data) {
122 	AudioStream *stream = (AudioStream *)data;
123 	RtpProfile *prof = rtp_session_get_profile(session);
124 	int payload = rtp_session_get_recv_payload_type(stream->ms.sessions.rtp_session);
125 	PayloadType *pt = rtp_profile_get_payload(prof, payload);
126 
127 	if (stream->ms.decoder == NULL){
128 		ms_message("audio_stream_payload_type_changed(): no decoder!");
129 		return FALSE;
130 	}
131 
132 	if (pt != NULL){
133 		MSFilter *dec;
134 		/* if new payload type is Comfort Noise (CN), just do nothing */
135 		if (strcasecmp(pt->mime_type, "CN")==0) {
136 			ms_message("Ignore payload type change to CN");
137 			return FALSE;
138 		}
139 
140 		if (stream->ms.current_pt && strcasecmp(pt->mime_type, stream->ms.current_pt->mime_type)==0 && pt->clock_rate==stream->ms.current_pt->clock_rate){
141 			ms_message("Ignoring payload type number change because it points to the same payload type as the current one");
142 			return FALSE;
143 		}
144 
145 		//dec = ms_filter_create_decoder(pt->mime_type);
146 		dec = ms_factory_create_decoder(stream->ms.factory, pt->mime_type);
147 		if (dec != NULL) {
148 			MSFilter *nextFilter = stream->ms.decoder->outputs[0]->next.filter;
149 
150 			ms_message("Replacing decoder on the fly");
151 			ms_filter_unlink(stream->ms.rtprecv, 0, stream->ms.decoder, 0);
152 			ms_filter_unlink(stream->ms.decoder, 0, nextFilter, 0);
153 			ms_filter_postprocess(stream->ms.decoder);
154 			ms_filter_destroy(stream->ms.decoder);
155 			stream->ms.decoder = dec;
156 			configure_decoder(stream, pt, stream->sample_rate, stream->nchannels);
157 			if (stream->write_resampler){
158 				audio_stream_configure_resampler(stream, stream->write_resampler,stream->ms.decoder,stream->soundwrite);
159 			}
160 			ms_filter_link(stream->ms.rtprecv, 0, stream->ms.decoder, 0);
161 			ms_filter_link(stream->ms.decoder, 0, nextFilter, 0);
162 			ms_filter_preprocess(stream->ms.decoder, stream->ms.sessions.ticker);
163 			stream->ms.current_pt=pt;
164 			return TRUE;
165 		} else {
166 			ms_error("No decoder found for %s", pt->mime_type);
167 		}
168 	} else {
169 		ms_warning("No payload type defined with number %i", payload);
170 	}
171 	return FALSE;
172 }
173 
174 /*
175  * note: since not all filters implement MS_FILTER_GET_SAMPLE_RATE and MS_FILTER_GET_NCHANNELS, the PayloadType passed here is used to guess this information.
176  */
audio_stream_configure_resampler(AudioStream * st,MSFilter * resampler,MSFilter * from,MSFilter * to)177 static void audio_stream_configure_resampler(AudioStream *st, MSFilter *resampler,MSFilter *from, MSFilter *to) {
178 	int from_rate=0, to_rate=0;
179 	int from_channels = 0, to_channels = 0;
180 	ms_filter_call_method(from,MS_FILTER_GET_SAMPLE_RATE,&from_rate);
181 	ms_filter_call_method(to,MS_FILTER_GET_SAMPLE_RATE,&to_rate);
182 	ms_filter_call_method(from, MS_FILTER_GET_NCHANNELS, &from_channels);
183 	ms_filter_call_method(to, MS_FILTER_GET_NCHANNELS, &to_channels);
184 	if (from_channels == 0) {
185 		from_channels = st->nchannels;
186 		ms_error("Filter %s does not implement the MS_FILTER_GET_NCHANNELS method", from->desc->name);
187 	}
188 	if (to_channels == 0) {
189 		to_channels = st->nchannels;
190 		ms_error("Filter %s does not implement the MS_FILTER_GET_NCHANNELS method", to->desc->name);
191 	}
192 	if (from_rate == 0){
193 		ms_error("Filter %s does not implement the MS_FILTER_GET_SAMPLE_RATE method", from->desc->name);
194 		from_rate = st->sample_rate;
195 	}
196 	if (to_rate == 0){
197 		ms_error("Filter %s does not implement the MS_FILTER_GET_SAMPLE_RATE method", to->desc->name);
198 		to_rate = st->sample_rate;
199 	}
200 	ms_filter_call_method(resampler,MS_FILTER_SET_SAMPLE_RATE,&from_rate);
201 	ms_filter_call_method(resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&to_rate);
202 	ms_filter_call_method(resampler, MS_FILTER_SET_NCHANNELS, &from_channels);
203 	ms_filter_call_method(resampler, MS_FILTER_SET_OUTPUT_NCHANNELS, &to_channels);
204 	ms_message("configuring %s:%p-->%s:%p from rate [%i] to rate [%i] and from channel [%i] to channel [%i]",
205 			   from->desc->name, from, to->desc->name, to, from_rate, to_rate, from_channels, to_channels);
206 }
207 
audio_stream_process_rtcp(MediaStream * media_stream,mblk_t * m)208 static void audio_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
209 }
210 
audio_stream_iterate(AudioStream * stream)211 void audio_stream_iterate(AudioStream *stream){
212 	media_stream_iterate(&stream->ms);
213 }
214 
audio_stream_alive(AudioStream * stream,int timeout)215 bool_t audio_stream_alive(AudioStream * stream, int timeout){
216 	return media_stream_alive((MediaStream*)stream,timeout);
217 }
218 
219 /*invoked from FEC capable filters*/
audio_stream_payload_picker(MSRtpPayloadPickerContext * context,unsigned int sequence_number)220 static  mblk_t* audio_stream_payload_picker(MSRtpPayloadPickerContext* context,unsigned int sequence_number) {
221 	return rtp_session_pick_with_cseq(((AudioStream*)(context->filter_graph_manager))->ms.sessions.rtp_session, sequence_number);
222 }
223 
stop_preload_graph(AudioStream * stream)224 static void stop_preload_graph(AudioStream *stream){
225 	ms_ticker_detach(stream->ms.sessions.ticker,stream->dummy);
226 
227 	if (stream->ms.voidsink) {
228 		ms_filter_unlink(stream->dummy,0,stream->ms.voidsink,0);
229 		ms_filter_destroy(stream->ms.voidsink);
230 		stream->ms.voidsink=NULL;
231 	}else if (stream->soundwrite) {
232 		int muted = 0;
233 		ms_filter_unlink(stream->dummy,0,stream->soundwrite,0);
234 		ms_filter_call_method(stream->soundwrite, MS_AUDIO_PLAYBACK_MUTE, &muted);
235 	}
236 	ms_filter_destroy(stream->dummy);
237 	stream->dummy=NULL;
238 }
239 
audio_stream_started(AudioStream * stream)240 bool_t audio_stream_started(AudioStream *stream){
241 	return media_stream_started(&stream->ms);
242 }
243 
244 /* This function is used either on IOS to workaround the long time to initialize the Audio Unit or for ICE candidates gathering. */
audio_stream_prepare_sound(AudioStream * stream,MSSndCard * playcard,MSSndCard * captcard)245 void audio_stream_prepare_sound(AudioStream *stream, MSSndCard *playcard, MSSndCard *captcard){
246 	audio_stream_unprepare_sound(stream);
247 	stream->dummy=ms_factory_create_filter(stream->ms.factory, MS_RTP_RECV_ID);
248 	rtp_session_set_payload_type(stream->ms.sessions.rtp_session,0);
249 	rtp_session_enable_rtcp(stream->ms.sessions.rtp_session, FALSE);
250 	ms_filter_call_method(stream->dummy,MS_RTP_RECV_SET_SESSION,stream->ms.sessions.rtp_session);
251 
252 	if (captcard && playcard){
253 #if TARGET_OS_IPHONE
254 		int muted = 1;
255 		stream->soundread=ms_snd_card_create_reader(captcard);
256 		stream->soundwrite=ms_snd_card_create_writer(playcard);
257 		ms_filter_link(stream->dummy,0,stream->soundwrite,0);
258 		ms_filter_call_method(stream->soundwrite, MS_AUDIO_PLAYBACK_MUTE, &muted);
259 #else
260 		stream->ms.voidsink=ms_factory_create_filter(stream->ms.factory,  MS_VOID_SINK_ID);
261 		ms_filter_link(stream->dummy,0,stream->ms.voidsink,0);
262 #endif
263 	} else {
264 		stream->ms.voidsink=ms_factory_create_filter(stream->ms.factory,  MS_VOID_SINK_ID);
265 		ms_filter_link(stream->dummy,0,stream->ms.voidsink,0);
266 
267 	}
268 	if (stream->ms.sessions.ticker == NULL) media_stream_start_ticker(&stream->ms);
269 	ms_ticker_attach(stream->ms.sessions.ticker,stream->dummy);
270 	stream->ms.state=MSStreamPreparing;
271 }
272 
_audio_stream_unprepare_sound(AudioStream * stream,bool_t keep_sound_resources)273 static void _audio_stream_unprepare_sound(AudioStream *stream, bool_t keep_sound_resources){
274 	if (stream->ms.state==MSStreamPreparing){
275 		stop_preload_graph(stream);
276 #if TARGET_OS_IPHONE
277 		if (!keep_sound_resources){
278 			if (stream->soundread) ms_filter_destroy(stream->soundread);
279 			stream->soundread=NULL;
280 			if (stream->soundwrite) ms_filter_destroy(stream->soundwrite);
281 			stream->soundwrite=NULL;
282 		}
283 #endif
284 	}
285 	stream->ms.state=MSStreamInitialized;
286 }
287 
audio_stream_unprepare_sound(AudioStream * stream)288 void audio_stream_unprepare_sound(AudioStream *stream){
289 	_audio_stream_unprepare_sound(stream,FALSE);
290 }
291 
player_callback(void * ud,MSFilter * f,unsigned int id,void * arg)292 static void player_callback(void *ud, MSFilter *f, unsigned int id, void *arg){
293 	AudioStream *stream=(AudioStream *)ud;
294 	int sr=0;
295 	int channels=0;
296 	switch(id){
297 		case MS_FILTER_OUTPUT_FMT_CHANGED:
298 			ms_filter_call_method(f,MS_FILTER_GET_SAMPLE_RATE,&sr);
299 			ms_filter_call_method(f,MS_FILTER_GET_NCHANNELS,&channels);
300 			if (f==stream->local_player){
301 				ms_filter_call_method(stream->local_player_resampler,MS_FILTER_SET_SAMPLE_RATE,&sr);
302 				ms_filter_call_method(stream->local_player_resampler,MS_FILTER_SET_NCHANNELS,&channels);
303 			}
304 		break;
305 		default:
306 		break;
307 	}
308 }
309 
setup_local_player(AudioStream * stream,int samplerate,int channels)310 static void setup_local_player(AudioStream *stream, int samplerate, int channels){
311 	MSConnectionHelper cnx;
312 	int master=0;
313 
314 
315 	stream->local_player=ms_factory_create_filter(stream->ms.factory, MS_FILE_PLAYER_ID);
316 	stream->local_player_resampler=ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID);
317 
318 	ms_connection_helper_start(&cnx);
319 	ms_connection_helper_link(&cnx,stream->local_player,-1,0);
320 	if (stream->local_player_resampler){
321 		ms_connection_helper_link(&cnx,stream->local_player_resampler,0,0);
322 	}
323 	ms_connection_helper_link(&cnx,stream->local_mixer,1,-1);
324 
325 	if (stream->local_player_resampler){
326 		ms_filter_call_method(stream->local_player_resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&samplerate);
327 		ms_filter_call_method(stream->local_player_resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&channels);
328 	}
329 	ms_filter_call_method(stream->local_mixer,MS_FILTER_SET_SAMPLE_RATE,&samplerate);
330 	ms_filter_call_method(stream->local_mixer,MS_FILTER_SET_NCHANNELS,&channels);
331 	ms_filter_call_method(stream->local_mixer,MS_AUDIO_MIXER_SET_MASTER_CHANNEL,&master);
332 	ms_filter_add_notify_callback(stream->local_player,player_callback,stream,TRUE);
333 }
334 
audio_stream_get_rtcp_xr_plc_status(void * userdata)335 static OrtpRtcpXrPlcStatus audio_stream_get_rtcp_xr_plc_status(void *userdata) {
336 	AudioStream *stream = (AudioStream *)userdata;
337 	if ((stream->features & AUDIO_STREAM_FEATURE_PLC) != 0) {
338 		int decoder_have_plc = 0;
339 		if (stream->ms.decoder && ms_filter_has_method(stream->ms.decoder, MS_AUDIO_DECODER_HAVE_PLC)) {
340 			ms_filter_call_method(stream->ms.decoder, MS_AUDIO_DECODER_HAVE_PLC, &decoder_have_plc);
341 		}
342 		if (decoder_have_plc == 0) {
343 			return OrtpRtcpXrSilencePlc;
344 		} else {
345 			return OrtpRtcpXrEnhancedPlc;
346 		}
347 	}
348 	return OrtpRtcpXrNoPlc;
349 }
350 
audio_stream_get_rtcp_xr_signal_level(void * userdata)351 static int audio_stream_get_rtcp_xr_signal_level(void *userdata) {
352 	AudioStream *stream = (AudioStream *)userdata;
353 	if ((stream->features & AUDIO_STREAM_FEATURE_VOL_RCV) != 0) {
354 		float volume = 0.f;
355 		if (stream->volrecv)
356 			ms_filter_call_method(stream->volrecv, MS_VOLUME_GET_MAX, &volume);
357 		return (int)volume;
358 	}
359 	return ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
360 }
361 
audio_stream_get_rtcp_xr_noise_level(void * userdata)362 static int audio_stream_get_rtcp_xr_noise_level(void *userdata) {
363 	AudioStream *stream = (AudioStream *)userdata;
364 	if ((stream->features & AUDIO_STREAM_FEATURE_VOL_RCV) != 0) {
365 		float volume = 0.f;
366 		if (stream->volrecv)
367 			ms_filter_call_method(stream->volrecv, MS_VOLUME_GET_MIN, &volume);
368 		return (int)volume;
369 	}
370 	return ORTP_RTCP_XR_UNAVAILABLE_PARAMETER;
371 }
372 
audio_stream_get_rtcp_xr_average_quality_rating(void * userdata)373 static float audio_stream_get_rtcp_xr_average_quality_rating(void *userdata) {
374 	AudioStream *stream = (AudioStream *)userdata;
375 	return audio_stream_get_average_quality_rating(stream);
376 }
377 
audio_stream_get_rtcp_xr_average_lq_quality_rating(void * userdata)378 static float audio_stream_get_rtcp_xr_average_lq_quality_rating(void *userdata) {
379 	AudioStream *stream = (AudioStream *)userdata;
380 	return audio_stream_get_average_lq_quality_rating(stream);
381 }
382 
ci_ends_with(const char * filename,const char * suffix)383 static bool_t ci_ends_with(const char *filename, const char*suffix){
384 	size_t filename_len=strlen(filename);
385 	size_t suffix_len=strlen(suffix);
386 	if (filename_len<suffix_len) return FALSE;
387 	return strcasecmp(filename+filename_len-suffix_len,suffix)==0;
388 }
389 
_ms_create_av_player(const char * filename,MSFactory * factory)390 MSFilter *_ms_create_av_player(const char *filename, MSFactory* factory){
391 	if (ci_ends_with(filename,".mkv"))
392 		return ms_factory_create_filter(factory, MS_MKV_PLAYER_ID);
393 	else if (ci_ends_with(filename,".wav"))
394 		return ms_factory_create_filter(factory, MS_FILE_PLAYER_ID);
395 	else
396 		ms_error("Cannot open %s, unsupported file extension", filename);
397 	return NULL;
398 }
399 
unplumb_av_player(AudioStream * stream)400 static void unplumb_av_player(AudioStream *stream){
401 	struct _AVPlayer *player=&stream->av_player;
402 	MSConnectionHelper ch;
403 	bool_t reattach=stream->ms.state==MSStreamStarted;
404 
405 	if (!player->plumbed) return;
406 
407 	/*detach the outbound graph before modifying the graph*/
408 	ms_ticker_detach(stream->ms.sessions.ticker,stream->soundread);
409 	if (player->videopin!=-1){
410 		ms_connection_helper_start(&ch);
411 		ms_connection_helper_unlink(&ch,player->player,-1,player->videopin);
412 		ms_connection_helper_unlink(&ch,player->video_output,0,0);
413 	}
414 	ms_connection_helper_start(&ch);
415 	ms_connection_helper_unlink(&ch,player->player,-1,player->audiopin);
416 	if (player->decoder)
417 		ms_connection_helper_unlink(&ch,player->decoder,0,0);
418 	ms_connection_helper_unlink(&ch,player->resampler,0,0);
419 	ms_connection_helper_unlink(&ch,stream->outbound_mixer,1,-1);
420 	/*and attach back*/
421 	if (reattach) ms_ticker_attach(stream->ms.sessions.ticker,stream->soundread);
422 	player->plumbed = FALSE;
423 }
424 
close_av_player(AudioStream * stream)425 static void close_av_player(AudioStream *stream){
426 	struct _AVPlayer *player=&stream->av_player;
427 
428 	if (player->player){
429 		MSPlayerState st=MSPlayerClosed;
430 		unplumb_av_player(stream);
431 		if (ms_filter_call_method(player->player,MS_PLAYER_GET_STATE,&st)==0){
432 			if (st!=MSPlayerClosed)
433 				ms_filter_call_method_noarg(player->player,MS_PLAYER_CLOSE);
434 		}
435 		ms_filter_destroy(player->player);
436 		player->player=NULL;
437 	}
438 	if (player->resampler){
439 		ms_filter_destroy(player->resampler);
440 		player->resampler=NULL;
441 	}
442 	if (player->decoder){
443 		ms_filter_destroy(player->decoder);
444 		player->decoder=NULL;
445 	}
446 }
447 
configure_av_player(AudioStream * stream,const MSFmtDescriptor * audiofmt,const MSFmtDescriptor * videofmt)448 static void configure_av_player(AudioStream *stream, const MSFmtDescriptor *audiofmt, const MSFmtDescriptor *videofmt){
449 	struct _AVPlayer *player=&stream->av_player;
450 	int stream_rate=0;
451 	int stream_channels=0;
452 
453 	ms_message("AudioStream [%p] Configure av_player, audiofmt=%s videofmt=%s",stream,ms_fmt_descriptor_to_string(audiofmt),ms_fmt_descriptor_to_string(videofmt));
454 
455 	if (audiofmt){
456 		if (player->decoder){
457 			if (audiofmt->nchannels>0){
458 				ms_filter_call_method(player->decoder,MS_FILTER_SET_NCHANNELS,(void*)&audiofmt->nchannels);
459 			}
460 			if (audiofmt->rate>0){
461 				ms_filter_call_method(player->decoder,MS_FILTER_SET_SAMPLE_RATE,(void*)&audiofmt->rate);
462 			}
463 		}
464 		ms_filter_call_method(player->resampler,MS_FILTER_SET_NCHANNELS,(void*)&audiofmt->nchannels);
465 		ms_filter_call_method(player->resampler,MS_FILTER_SET_SAMPLE_RATE,(void*)&audiofmt->rate);
466 	}
467 
468 	ms_filter_call_method(stream->outbound_mixer,MS_FILTER_GET_SAMPLE_RATE,&stream_rate);
469 	ms_filter_call_method(stream->outbound_mixer,MS_FILTER_GET_NCHANNELS,&stream_channels);
470 	ms_filter_call_method(player->resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&stream_channels);
471 	ms_filter_call_method(player->resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&stream_rate);
472 	if (videofmt){
473 		MSPinFormat pf;
474 		pf.pin=0;
475 		pf.fmt=videofmt;
476 		ms_filter_call_method(player->video_output,MS_FILTER_SET_INPUT_FMT,&pf);
477 	}
478 }
479 
plumb_av_player(AudioStream * stream)480 static void plumb_av_player(AudioStream *stream){
481 	struct _AVPlayer *player=&stream->av_player;
482 	MSConnectionHelper ch;
483 	bool_t reattach=stream->ms.state==MSStreamStarted;
484 
485 	if (player->videopin!=-1){
486 		ms_connection_helper_start(&ch);
487 		ms_connection_helper_link(&ch,player->player,-1,player->videopin);
488 		ms_connection_helper_link(&ch,player->video_output,0,0);
489 	}
490 	ms_connection_helper_start(&ch);
491 	ms_connection_helper_link(&ch,player->player,-1,player->audiopin);
492 	if (player->decoder)
493 		ms_connection_helper_link(&ch,player->decoder,0,0);
494 	ms_connection_helper_link(&ch,player->resampler,0,0);
495 	/*detach the outbound graph before attaching to the outbound mixer*/
496 	if (reattach) ms_ticker_detach(stream->ms.sessions.ticker,stream->soundread);
497 	ms_connection_helper_link(&ch,stream->outbound_mixer,1,-1);
498 	/*and attach back*/
499 	if (reattach) ms_ticker_attach(stream->ms.sessions.ticker,stream->soundread);
500 	player->plumbed=TRUE;
501 }
502 
open_av_player(AudioStream * stream,const char * filename)503 static int open_av_player(AudioStream *stream, const char *filename){
504 	struct _AVPlayer *player=&stream->av_player;
505 	MSPinFormat fmt1={0},fmt2={0};
506 	MSPinFormat *audiofmt=NULL;
507 	MSPinFormat *videofmt=NULL;
508 
509 	if (player->player) close_av_player(stream);
510 	//player->player=_ms_create_av_player(filename);
511 	player->player=_ms_create_av_player(filename, stream->ms.factory);
512 	if (player->player==NULL){
513 		ms_warning("AudioStream[%p]: no way to open [%s].",stream,filename);
514 		return -1;
515 	}
516 	if (ms_filter_call_method(player->player,MS_PLAYER_OPEN,(void*)filename)==-1){
517 		close_av_player(stream);
518 		return -1;
519 	}
520 	fmt1.pin=0;
521 	ms_filter_call_method(player->player,MS_FILTER_GET_OUTPUT_FMT,&fmt1);
522 	fmt2.pin=1;
523 	ms_filter_call_method(player->player,MS_FILTER_GET_OUTPUT_FMT,&fmt2);
524 	if (fmt1.fmt==NULL && fmt2.fmt==NULL){
525 		/*assume PCM*/
526 		int sr=8000;
527 		int channels=1;
528 		ms_filter_call_method(player->player,MS_FILTER_GET_SAMPLE_RATE,&sr);
529 		ms_filter_call_method(player->player,MS_FILTER_GET_NCHANNELS,&channels);
530 		fmt1.fmt=ms_factory_get_audio_format(stream->ms.factory, "pcm", sr, channels, NULL);
531 		audiofmt=&fmt1;
532 	}else{
533 		if (fmt1.fmt) {
534 			if (fmt1.fmt->type==MSAudio){
535 				audiofmt=&fmt1;
536 				player->audiopin=0;
537 			}else{
538 				videofmt=&fmt1;
539 				player->videopin=0;
540 			}
541 		}
542 		if (fmt2.fmt){
543 			if (fmt2.fmt->type == MSAudio){
544 				audiofmt=&fmt2;
545 				player->audiopin=1;
546 			}else{
547 				videofmt=&fmt2;
548 				player->videopin=1;
549 			}
550 
551 		}
552 	}
553 	if (audiofmt && audiofmt->fmt && strcasecmp(audiofmt->fmt->encoding,"pcm")!=0){
554 		player->decoder=ms_factory_create_decoder(stream->ms.factory, audiofmt->fmt->encoding);
555 
556 		if (player->decoder==NULL){
557 			ms_warning("AudioStream[%p]: no way to decode [%s]",stream,filename);
558 			close_av_player(stream);
559 			return -1;
560 		}
561 	}
562 	player->resampler=ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID);
563 	if (videofmt && videofmt->fmt) player->video_output=ms_factory_create_filter(stream->videostream->ms.factory,MS_ITC_SINK_ID);
564 
565 	else player->videopin=-1;
566 	configure_av_player(stream,audiofmt ? audiofmt->fmt : NULL ,videofmt ? videofmt->fmt : NULL);
567 	if (stream->videostream) video_stream_open_player(stream->videostream,player->video_output);
568 	plumb_av_player(stream);
569 	return 0;
570 }
571 
audio_stream_open_remote_play(AudioStream * stream,const char * filename)572 MSFilter * audio_stream_open_remote_play(AudioStream *stream, const char *filename){
573 	if (stream->ms.state!=MSStreamStarted){
574 		ms_warning("AudioStream[%p]: audio_stream_play_to_remote() works only when the stream is started.",stream);
575 		return NULL;
576 	}
577 	if (stream->outbound_mixer==NULL){
578 		ms_warning("AudioStream[%p]: audio_stream_play_to_remote() works only when the stream has AUDIO_STREAM_FEATURE_REMOTE_PLAYING capability.",stream);
579 		return NULL;
580 	}
581 	if (open_av_player(stream,filename)==-1){
582 		return NULL;
583 	}
584 	return stream->av_player.player;
585 }
586 
audio_stream_close_remote_play(AudioStream * stream)587 void audio_stream_close_remote_play(AudioStream *stream){
588 	MSPlayerState state;
589 	if (stream->av_player.player){
590 		ms_filter_call_method(stream->av_player.player,MS_PLAYER_GET_STATE,&state);
591 		if (state!=MSPlayerClosed)
592 			ms_filter_call_method_noarg(stream->av_player.player,MS_PLAYER_CLOSE);
593 	}
594 	if (stream->videostream) video_stream_close_player(stream->videostream);
595 }
596 
video_input_updated(void * stream,MSFilter * f,unsigned int event_id,void * arg)597 static void video_input_updated(void *stream, MSFilter *f, unsigned int event_id, void *arg){
598 	if (event_id==MS_FILTER_OUTPUT_FMT_CHANGED){
599 		ms_message("Video ITC source updated.");
600 		configure_av_recorder((AudioStream*)stream);
601 	}
602 }
603 
av_recorder_handle_event(void * userdata,MSFilter * recorder,unsigned int event,void * event_arg)604 static void av_recorder_handle_event(void *userdata, MSFilter *recorder, unsigned int event, void *event_arg){
605 #ifdef VIDEO_ENABLED
606 	AudioStream *audiostream = (AudioStream *)userdata;
607 	if (audiostream->videostream != NULL) {
608 		video_recorder_handle_event(audiostream->videostream, recorder, event, event_arg);
609 	}
610 #endif
611 }
612 
setup_av_recorder(AudioStream * stream,int sample_rate,int nchannels)613 static void setup_av_recorder(AudioStream *stream, int sample_rate, int nchannels){
614 
615 	stream->av_recorder.recorder=ms_factory_create_filter(stream->ms.factory, MS_MKV_RECORDER_ID);
616 	if (stream->av_recorder.recorder){
617 		MSPinFormat pinfmt={0};
618 		stream->av_recorder.video_input=ms_factory_create_filter(stream->ms.factory, MS_ITC_SOURCE_ID);
619 		stream->av_recorder.resampler=ms_factory_create_filter(stream->ms.factory,MS_RESAMPLE_ID);
620 		stream->av_recorder.encoder=ms_factory_create_filter(stream->ms.factory,MS_OPUS_ENC_ID);
621 
622 		if (stream->av_recorder.encoder==NULL){
623 			int g711_rate=8000;
624 			int g711_nchannels=1;
625 			stream->av_recorder.encoder=ms_factory_create_filter(stream->ms.factory, MS_ULAW_ENC_ID);
626 			ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
627 			ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&g711_rate);
628 			ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_NCHANNELS,&nchannels);
629 			ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&g711_nchannels);
630 			pinfmt.fmt=ms_factory_get_audio_format(stream->ms.factory, "pcmu",g711_rate,g711_nchannels,NULL);
631 
632 		}else{
633 			int got_sr=0;
634 			ms_filter_call_method(stream->av_recorder.encoder,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
635 			ms_filter_call_method(stream->av_recorder.encoder,MS_FILTER_GET_SAMPLE_RATE,&got_sr);
636 			ms_filter_call_method(stream->av_recorder.encoder,MS_FILTER_SET_NCHANNELS,&nchannels);
637 			ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
638 			ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&got_sr);
639 			ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_NCHANNELS,&nchannels);
640 			ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&nchannels);
641 			pinfmt.fmt=ms_factory_get_audio_format(stream->ms.factory,"opus",48000,nchannels,NULL);
642 		}
643 		pinfmt.pin=1;
644 		ms_message("Configuring av recorder with audio format %s",ms_fmt_descriptor_to_string(pinfmt.fmt));
645 		ms_filter_call_method(stream->av_recorder.recorder,MS_FILTER_SET_INPUT_FMT,&pinfmt);
646 		ms_filter_add_notify_callback(stream->av_recorder.video_input,video_input_updated,stream,TRUE);
647 		ms_filter_add_notify_callback(stream->av_recorder.recorder, av_recorder_handle_event, stream, TRUE);
648 	}
649 }
650 
plumb_av_recorder(AudioStream * stream)651 static void plumb_av_recorder(AudioStream *stream){
652 	MSConnectionHelper ch;
653 	ms_connection_helper_start(&ch);
654 	ms_connection_helper_link(&ch, stream->recorder_mixer,-1, 1);
655 	ms_connection_helper_link(&ch, stream->av_recorder.resampler,0,0);
656 	ms_connection_helper_link(&ch, stream->av_recorder.encoder,0,0);
657 	ms_connection_helper_link(&ch, stream->av_recorder.recorder,1,-1);
658 
659 	ms_filter_link(stream->av_recorder.video_input,0,stream->av_recorder.recorder,0);
660 }
661 
unplumb_av_recorder(AudioStream * stream)662 static void unplumb_av_recorder(AudioStream *stream){
663 	MSConnectionHelper ch;
664 	MSRecorderState rstate;
665 	ms_connection_helper_start(&ch);
666 	ms_connection_helper_unlink(&ch, stream->recorder_mixer,-1, 1);
667 	ms_connection_helper_unlink(&ch, stream->av_recorder.resampler,0,0);
668 	ms_connection_helper_unlink(&ch, stream->av_recorder.encoder,0,0);
669 	ms_connection_helper_unlink(&ch, stream->av_recorder.recorder,1,-1);
670 
671 	ms_filter_unlink(stream->av_recorder.video_input,0,stream->av_recorder.recorder,0);
672 
673 	if (ms_filter_call_method(stream->av_recorder.recorder,MS_RECORDER_GET_STATE,&rstate)==0){
674 		if (rstate!=MSRecorderClosed){
675 			ms_filter_call_method_noarg(stream->av_recorder.recorder, MS_RECORDER_CLOSE);
676 		}
677 	}
678 }
679 
setup_recorder(AudioStream * stream,int sample_rate,int nchannels)680 static void setup_recorder(AudioStream *stream, int sample_rate, int nchannels){
681 	int val=0;
682 	int pin=1;
683 	MSAudioMixerCtl mctl={0};
684 
685 	stream->recorder=ms_factory_create_filter(stream->ms.factory, MS_FILE_REC_ID);
686 	stream->recorder_mixer=ms_factory_create_filter(stream->ms.factory, MS_AUDIO_MIXER_ID);
687 	stream->recv_tee=ms_factory_create_filter(stream->ms.factory, MS_TEE_ID);
688 
689 	ms_filter_call_method(stream->recorder_mixer,MS_AUDIO_MIXER_ENABLE_CONFERENCE_MODE,&val);
690 	ms_filter_call_method(stream->recorder_mixer,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
691 	ms_filter_call_method(stream->recorder_mixer,MS_FILTER_SET_NCHANNELS,&nchannels);
692 	ms_filter_call_method(stream->recv_tee,MS_TEE_MUTE,&pin);
693 	mctl.pin=pin;
694 	mctl.param.enabled=FALSE;
695 	ms_filter_call_method(stream->outbound_mixer,MS_AUDIO_MIXER_ENABLE_OUTPUT,&mctl);
696 	ms_filter_call_method(stream->recorder,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
697 	ms_filter_call_method(stream->recorder,MS_FILTER_SET_NCHANNELS,&nchannels);
698 
699 	setup_av_recorder(stream,sample_rate,nchannels);
700 }
701 
on_silence_detected(void * data,MSFilter * f,unsigned int event_id,void * event_arg)702 static void on_silence_detected(void *data, MSFilter *f, unsigned int event_id, void *event_arg){
703 	AudioStream *as=(AudioStream*)data;
704 	if (as->ms.rtpsend){
705 		switch(event_id){
706 			case MS_VAD_DTX_NO_VOICE:
707 				/*ms_message("on_silence_detected(): CN packet to be sent !");*/
708 				ms_filter_call_method(as->ms.rtpsend, MS_RTP_SEND_SEND_GENERIC_CN, event_arg);
709 				ms_filter_call_method(as->ms.rtpsend, MS_RTP_SEND_MUTE, event_arg);
710 			break;
711 			case MS_VAD_DTX_VOICE:
712 				/*ms_message("on_silence_detected(): resuming audio");*/
713 				ms_filter_call_method(as->ms.rtpsend, MS_RTP_SEND_UNMUTE, event_arg);
714 			break;
715 		}
716 	}
717 }
718 
on_cn_received(void * data,MSFilter * f,unsigned int event_id,void * event_arg)719 static void on_cn_received(void *data, MSFilter *f, unsigned int event_id, void *event_arg){
720 	AudioStream *as=(AudioStream*)data;
721 	if (as->plc){
722 		ms_message("CN packet received, given to MSGenericPlc filter.");
723 		ms_filter_call_method(as->plc, MS_GENERIC_PLC_SET_CN, event_arg);
724 	}
725 }
726 
setup_generic_confort_noise(AudioStream * stream)727 static void setup_generic_confort_noise(AudioStream *stream){
728 	RtpProfile *prof=rtp_session_get_profile(stream->ms.sessions.rtp_session);
729 	PayloadType *pt=rtp_profile_get_payload(prof, rtp_session_get_send_payload_type(stream->ms.sessions.rtp_session));
730 	int cn = rtp_profile_get_payload_number_from_mime_and_flag(prof, "CN", PAYLOAD_TYPE_FLAG_CAN_SEND);
731 
732 	if (cn >= 0 && pt && pt->channels==1){
733 		int samplerate = pt->clock_rate;
734 		ms_filter_call_method(stream->ms.decoder, MS_FILTER_GET_SAMPLE_RATE, &samplerate);
735 		if (samplerate == 8000){
736 			/* RFC3389 CN can be used only for 8khz codecs*/
737 			stream->vaddtx=ms_factory_create_filter(stream->ms.factory, MS_VAD_DTX_ID);
738 			if (stream->vaddtx) {
739 				ms_filter_add_notify_callback(stream->vaddtx, on_silence_detected, stream, TRUE);
740 				ms_filter_add_notify_callback(stream->ms.rtprecv, on_cn_received, stream, TRUE);
741 			} else {
742 				ms_warning("Cannot instantiate vaddtx filter!");
743 			}
744 
745 		}
746 	}
747 }
748 
configure_decoder(AudioStream * stream,PayloadType * pt,int sample_rate,int nchannels)749 static void configure_decoder(AudioStream *stream, PayloadType *pt, int sample_rate, int nchannels){
750 	ms_filter_call_method(stream->ms.decoder,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
751 	ms_filter_call_method(stream->ms.decoder,MS_FILTER_SET_NCHANNELS,&nchannels);
752 	if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->ms.decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp);
753 	if (ms_filter_has_method(stream->ms.decoder, MS_AUDIO_DECODER_SET_RTP_PAYLOAD_PICKER) || ms_filter_has_method(stream->ms.decoder, MS_FILTER_SET_RTP_PAYLOAD_PICKER)) {
754 		MSRtpPayloadPickerContext picker_context;
755 		ms_message("Decoder has FEC capabilities");
756 		picker_context.filter_graph_manager=stream;
757 		picker_context.picker=&audio_stream_payload_picker;
758 		ms_filter_call_method(stream->ms.decoder,MS_AUDIO_DECODER_SET_RTP_PAYLOAD_PICKER, &picker_context);
759 	}
760 }
761 
get_usable_telephone_event(RtpProfile * profile,int clock_rate)762 static int get_usable_telephone_event(RtpProfile *profile, int clock_rate){
763 	int i;
764 	int fallback_pt=-1;
765 	for(i=0; i<128; ++i){
766 		PayloadType *pt = profile->payload[i];
767 		if (pt && strcasecmp(pt->mime_type, "telephone-event")==0 && (pt->flags & PAYLOAD_TYPE_FLAG_CAN_SEND)){
768 			if (pt->clock_rate == clock_rate)
769 				return i;
770 			if (pt->clock_rate == 8000)
771 				fallback_pt = i;
772 		}
773 	}
774 	/*
775 	 * the fallback payload type is used if the remote equipment doesn't conform to RFC4733 2.1,
776 	 * that requires to use a clock rate which is the same as the audio codec.
777 	 */
778 	if (fallback_pt !=-1) ms_warning("The remote equipment doesn't conform to RFC4733 2.1 - it wants to use telephone-event/8000 despite the clock rate of the audio codec is %i", clock_rate);
779 	return fallback_pt;
780 }
781 
audio_stream_start_from_io(AudioStream * stream,RtpProfile * profile,const char * rem_rtp_ip,int rem_rtp_port,const char * rem_rtcp_ip,int rem_rtcp_port,int payload,const MSMediaStreamIO * io)782 int audio_stream_start_from_io(AudioStream *stream, RtpProfile *profile, const char *rem_rtp_ip, int rem_rtp_port,
783 	const char *rem_rtcp_ip, int rem_rtcp_port, int payload, const MSMediaStreamIO *io) {
784 	RtpSession *rtps=stream->ms.sessions.rtp_session;
785 	PayloadType *pt;
786 	int tmp, tev_pt;
787 	MSConnectionHelper h;
788 	int sample_rate;
789 	int nchannels;
790 	int err1,err2;
791 	bool_t has_builtin_ec=FALSE;
792 	bool_t resampler_missing = FALSE;
793 	bool_t skip_encoder_and_decoder = FALSE;
794 	bool_t do_ts_adjustments = TRUE;
795 
796 	if (!ms_media_stream_io_is_consistent(io)) return -1;
797 
798 	rtp_session_set_profile(rtps,profile);
799 	if (rem_rtp_port>0) rtp_session_set_remote_addr_full(rtps,rem_rtp_ip,rem_rtp_port,rem_rtcp_ip,rem_rtcp_port);
800 	if (rem_rtcp_port > 0) {
801 		rtp_session_enable_rtcp(rtps, TRUE);
802 	} else {
803 		rtp_session_enable_rtcp(rtps, FALSE);
804 	}
805 	rtp_session_set_payload_type(rtps,payload);
806 
807 	ms_filter_call_method(stream->ms.rtpsend,MS_RTP_SEND_SET_SESSION,rtps);
808 	stream->ms.rtprecv=ms_factory_create_filter(stream->ms.factory,MS_RTP_RECV_ID);
809 	ms_filter_call_method(stream->ms.rtprecv,MS_RTP_RECV_SET_SESSION,rtps);
810 	stream->ms.sessions.rtp_session=rtps;
811 
812 	if((stream->features & AUDIO_STREAM_FEATURE_DTMF_ECHO) != 0)
813 		stream->dtmfgen=ms_factory_create_filter(stream->ms.factory, MS_DTMF_GEN_ID);
814 	else
815 		stream->dtmfgen=NULL;
816 	rtp_session_signal_connect(rtps,"telephone-event",(RtpCallback)on_dtmf_received,stream);
817 	rtp_session_signal_connect(rtps,"payload_type_changed",(RtpCallback)audio_stream_payload_type_changed,stream);
818 
819 	if (stream->ms.state==MSStreamPreparing){
820 		/*we were using the dummy preload graph, destroy it but keep sound filters unless no soundcard is given*/
821 		_audio_stream_unprepare_sound(stream, io->input.type == MSResourceSoundcard);
822 	}
823 
824 	/* creates the local part */
825 	if (io->input.type == MSResourceSoundcard){
826 		if (stream->soundread==NULL)
827 			stream->soundread = ms_snd_card_create_reader(io->input.soundcard);
828 		has_builtin_ec=!!(ms_snd_card_get_capabilities(io->input.soundcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER);
829 	} else if (io->input.type == MSResourceRtp) {
830 		stream->rtp_io_session = io->input.session;
831 		pt = rtp_profile_get_payload(rtp_session_get_profile(stream->rtp_io_session),
832 			rtp_session_get_recv_payload_type(stream->rtp_io_session));
833 		stream->soundread = ms_factory_create_filter(stream->ms.factory, MS_RTP_RECV_ID);
834 		ms_filter_call_method(stream->soundread, MS_RTP_RECV_SET_SESSION, stream->rtp_io_session);
835 		stream->read_decoder = ms_factory_create_decoder(stream->ms.factory, pt->mime_type);
836 	} else {
837 		stream->soundread=ms_factory_create_filter(stream->ms.factory, MS_FILE_PLAYER_ID);
838 		stream->read_resampler=ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID);
839 		resampler_missing = stream->read_resampler == NULL;
840 	}
841 	if (io->output.type == MSResourceSoundcard) {
842 		if (stream->soundwrite==NULL)
843 			stream->soundwrite=ms_snd_card_create_writer(io->output.soundcard);
844 	} else if (io->output.type == MSResourceRtp) {
845 		stream->rtp_io_session = io->output.session;
846 		pt = rtp_profile_get_payload(rtp_session_get_profile(stream->rtp_io_session),
847 			rtp_session_get_send_payload_type(stream->rtp_io_session));
848 		stream->soundwrite = ms_factory_create_filter(stream->ms.factory, MS_RTP_SEND_ID);
849 		ms_filter_call_method(stream->soundwrite, MS_RTP_SEND_SET_SESSION, stream->rtp_io_session);
850 		stream->write_encoder = ms_factory_create_encoder(stream->ms.factory,pt->mime_type);
851 	} else {
852 		stream->soundwrite=ms_factory_create_filter(stream->ms.factory, MS_FILE_REC_ID);
853 	}
854 
855 	/* creates the couple of encoder/decoder */
856 	pt=rtp_profile_get_payload(profile,payload);
857 	if (pt==NULL){
858 		ms_error("audiostream.c: undefined payload type.");
859 		return -1;
860 	}
861 	nchannels=pt->channels;
862 	stream->ms.current_pt=pt;
863 	tev_pt = get_usable_telephone_event(profile, pt->clock_rate);
864 
865 	if ((stream->features & AUDIO_STREAM_FEATURE_DTMF) != 0 && (tev_pt == -1)
866 		&& ( strcasecmp(pt->mime_type,"pcmu")==0 || strcasecmp(pt->mime_type,"pcma")==0)){
867 		/*if no telephone-event payload is usable and pcma or pcmu is used, we will generate
868 		  inband dtmf*/
869 		stream->dtmfgen_rtp=ms_factory_create_filter (stream->ms.factory, MS_DTMF_GEN_ID);
870 
871 	} else {
872 		stream->dtmfgen_rtp=NULL;
873 	}
874 	if (tev_pt != -1)
875 		rtp_session_set_send_telephone_event_payload_type(rtps, tev_pt);
876 
877 	if (ms_filter_call_method(stream->ms.rtpsend,MS_FILTER_GET_SAMPLE_RATE,&sample_rate)!=0){
878 		ms_error("Sample rate is unknown for RTP side !");
879 		return -1;
880 	}
881 
882 	if (stream->features == 0) {
883 		MSPinFormat sndread_format = {0};
884 		MSPinFormat rtpsend_format = {0};
885 		MSPinFormat rtprecv_format = {0};
886 		MSPinFormat sndwrite_format = {0};
887 		ms_filter_call_method(stream->ms.rtpsend, MS_FILTER_GET_OUTPUT_FMT, &rtpsend_format);
888 		ms_filter_call_method(stream->soundread, MS_FILTER_GET_OUTPUT_FMT, &sndread_format);
889 		ms_filter_call_method(stream->ms.rtprecv, MS_FILTER_GET_OUTPUT_FMT, &rtprecv_format);
890 		ms_filter_call_method(stream->soundwrite, MS_FILTER_GET_OUTPUT_FMT, &sndwrite_format);
891 		if (sndread_format.fmt && rtpsend_format.fmt && rtprecv_format.fmt && sndwrite_format.fmt) {
892 			skip_encoder_and_decoder = ms_fmt_descriptor_equals(sndread_format.fmt, rtpsend_format.fmt) && ms_fmt_descriptor_equals(rtprecv_format.fmt, sndwrite_format.fmt);
893 		}
894 	}
895 	do_ts_adjustments = !skip_encoder_and_decoder;
896 	ms_filter_call_method(stream->ms.rtpsend, MS_RTP_SEND_ENABLE_TS_ADJUSTMENT, &do_ts_adjustments);
897 
898 	if (!skip_encoder_and_decoder) {
899 		stream->ms.encoder=ms_factory_create_encoder(stream->ms.factory, pt->mime_type);
900 		stream->ms.decoder=ms_factory_create_decoder(stream->ms.factory, pt->mime_type);
901 	}
902 
903 	/* sample rate is already set for rtpsend and rtprcv, check if we have to adjust it to */
904 	/* be able to use the echo canceller wich may be limited (webrtc aecm max frequency is 16000 Hz) */
905 	// First check if we need to use the echo canceller
906 	// Overide feature if not requested or done at sound card level
907 	if ( ((stream->features & AUDIO_STREAM_FEATURE_EC) && !stream->use_ec) || has_builtin_ec )
908 		stream->features &=~AUDIO_STREAM_FEATURE_EC;
909 
910 	/*configure the echo canceller if required */
911 	if ((stream->features & AUDIO_STREAM_FEATURE_EC) == 0 && stream->ec != NULL) {
912 		ms_filter_destroy(stream->ec);
913 		stream->ec=NULL;
914 	}
915 
916 	if (!skip_encoder_and_decoder && (stream->ms.encoder==NULL || stream->ms.decoder==NULL)){
917 		/* big problem: we have not a registered codec for this payload...*/
918 		ms_error("audio_stream_start_from_io: No decoder or encoder available for payload %s.",pt->mime_type);
919 		return -1;
920 	}
921 
922 	/* check echo canceller max frequency and adjust sampling rate if needed when codec used is opus */
923 	if (stream->ec!=NULL) {
924 		int ec_sample_rate = sample_rate;
925 		ms_filter_call_method(stream->ec, MS_FILTER_SET_SAMPLE_RATE, &sample_rate);
926 		ms_filter_call_method(stream->ec, MS_FILTER_GET_SAMPLE_RATE, &ec_sample_rate);
927 		if (sample_rate != ec_sample_rate) {
928 			if (ms_filter_get_id(stream->ms.encoder) == MS_OPUS_ENC_ID) {
929 				sample_rate = ec_sample_rate;
930 				ms_message("Sampling rate forced to %iHz to allow the use of echo canceller", sample_rate);
931 			} else {
932 				ms_warning("Echo canceller does not support sampling rate %iHz, so it has been disabled", sample_rate);
933 				ms_filter_destroy(stream->ec);
934 				stream->ec = NULL;
935 			}
936 		}
937 		/*in any case, our software AEC filters do not support stereo operation, so force channels to be 1*/
938 		nchannels=1;
939 	}
940 	/*hack for opus, that claims stereo all the time, but we can't support stereo yet*/
941 	if (strcasecmp(pt->mime_type,"opus")==0){
942 		if ( (stream->features & (~(AUDIO_STREAM_FEATURE_PLC|AUDIO_STREAM_FEATURE_REMOTE_PLAYING)) ) != 0){
943 			/*all features except PLC and REMOTE_PLAYING prevent from activating the stereo*/
944 			ms_message("opus stereo support is deactivated because of incompatible features targeted for this AudioStream");
945 			nchannels=1;
946 		}else{
947 			ms_message("Full stereo enabled in this audiostream.");
948 		}
949 	}
950 	stream->sample_rate=sample_rate;
951 	stream->nchannels=nchannels;
952 
953 	if ((stream->features & AUDIO_STREAM_FEATURE_VOL_SND) != 0)
954 		stream->volsend=ms_factory_create_filter(stream->ms.factory, MS_VOLUME_ID);
955 			else
956 		stream->volsend=NULL;
957 	if ((stream->features & AUDIO_STREAM_FEATURE_VOL_RCV) != 0)
958 		stream->volrecv=ms_factory_create_filter(stream->ms.factory, MS_VOLUME_ID);
959 
960 	else
961 		stream->volrecv=NULL;
962 
963 	audio_stream_enable_echo_limiter(stream,stream->el_type);
964 	audio_stream_enable_noise_gate(stream,stream->use_ng);
965 
966 	if (ms_filter_implements_interface(stream->soundread,MSFilterPlayerInterface) && io->input.file){
967 		audio_stream_play(stream,io->input.file);
968 	}
969 	if (ms_filter_implements_interface(stream->soundwrite,MSFilterRecorderInterface) && io->output.file){
970 		audio_stream_record(stream,io->output.file);
971 	}
972 
973 	if (stream->use_agc){
974 		int tmp=1;
975 		if (stream->volsend==NULL)
976 			stream->volsend=ms_factory_create_filter(stream->ms.factory, MS_VOLUME_ID);
977 		ms_filter_call_method(stream->volsend,MS_VOLUME_ENABLE_AGC,&tmp);
978 	}
979 
980 	if (stream->dtmfgen) {
981 		ms_filter_call_method(stream->dtmfgen,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
982 		ms_filter_call_method(stream->dtmfgen,MS_FILTER_SET_NCHANNELS,&nchannels);
983 	}
984 	if (stream->dtmfgen_rtp) {
985 		ms_filter_call_method(stream->dtmfgen_rtp,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
986 		ms_filter_call_method(stream->dtmfgen_rtp,MS_FILTER_SET_NCHANNELS,&nchannels);
987 	}
988 
989 	/*don't put these two statements in a single if, because the second one will not be executed if the first one evaluates as true*/
990 	err1 = ms_filter_call_method(stream->soundread, MS_FILTER_SET_SAMPLE_RATE, &sample_rate);
991 	err2 = ms_filter_call_method(stream->soundread, MS_FILTER_SET_NCHANNELS, &nchannels);
992 	/* give the sound filters some properties */
993 	if (err1 != 0 || err2 != 0){
994 		/* need to add resampler*/
995 		if (stream->read_resampler == NULL) stream->read_resampler = ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID);
996 		resampler_missing = stream->read_resampler == NULL;
997 	}
998 
999 	err1 = ms_filter_call_method(stream->soundwrite, MS_FILTER_SET_SAMPLE_RATE, &sample_rate);
1000 	err2 = ms_filter_call_method(stream->soundwrite, MS_FILTER_SET_NCHANNELS, &nchannels);
1001 	if (err1 !=0 || err2 != 0){
1002 		/* need to add resampler*/
1003 		if (stream->write_resampler == NULL) stream->write_resampler = ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID);
1004 		resampler_missing = stream->write_resampler == NULL;
1005 	}
1006 
1007 	if (resampler_missing){
1008 		ms_fatal("AudioStream: no resampler implementation found, but resampler is required to perform the AudioStream. "
1009 			"Does mediastreamer2 was compiled with libspeex dependency ?");
1010 	}
1011 
1012 	if (stream->ec){
1013 		if (!stream->is_ec_delay_set) {
1014 			int delay_ms=ms_snd_card_get_minimal_latency(io->input.soundcard);
1015 			ms_message("Setting echo canceller delay with value provided by soundcard: %i ms",delay_ms);
1016 			ms_filter_call_method(stream->ec,MS_ECHO_CANCELLER_SET_DELAY,&delay_ms);
1017 		} else {
1018 			ms_message("Setting echo canceller delay with value configured by application.");
1019 		}
1020 		ms_filter_call_method(stream->ec,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
1021 	}
1022 
1023 	if (stream->features & AUDIO_STREAM_FEATURE_MIXED_RECORDING || stream->features & AUDIO_STREAM_FEATURE_REMOTE_PLAYING){
1024 		stream->outbound_mixer=ms_factory_create_filter(stream->ms.factory, MS_AUDIO_MIXER_ID);
1025 	}
1026 
1027 	if (stream->features & AUDIO_STREAM_FEATURE_MIXED_RECORDING) setup_recorder(stream,sample_rate,nchannels);
1028 
1029 	if (!skip_encoder_and_decoder) {
1030 		/* give the encoder/decoder some parameters*/
1031 		ms_filter_call_method(stream->ms.encoder,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
1032 		if (stream->ms.target_bitrate<=0) {
1033 			stream->ms.target_bitrate=pt->normal_bitrate;
1034 			ms_message("target bitrate not set for stream [%p] using payload's bitrate is %i",stream,stream->ms.target_bitrate);
1035 		}
1036 		if (stream->ms.target_bitrate>0){
1037 			ms_message("Setting audio encoder network bitrate to [%i] on stream [%p]",stream->ms.target_bitrate,stream);
1038 			ms_filter_call_method(stream->ms.encoder,MS_FILTER_SET_BITRATE,&stream->ms.target_bitrate);
1039 		}
1040 		rtp_session_set_target_upload_bandwidth(rtps, stream->ms.target_bitrate);
1041 		ms_filter_call_method(stream->ms.encoder,MS_FILTER_SET_NCHANNELS,&nchannels);
1042 		if (pt->send_fmtp!=NULL) {
1043 			char value[16]={0};
1044 			int ptime;
1045 			if (ms_filter_has_method(stream->ms.encoder,MS_AUDIO_ENCODER_SET_PTIME)){
1046 				if (fmtp_get_value(pt->send_fmtp,"ptime",value,sizeof(value)-1)){
1047 					ptime=atoi(value);
1048 					ms_filter_call_method(stream->ms.encoder,MS_AUDIO_ENCODER_SET_PTIME,&ptime);
1049 				}
1050 			}
1051 			ms_filter_call_method(stream->ms.encoder,MS_FILTER_ADD_FMTP, (void*)pt->send_fmtp);
1052 		}
1053 
1054 		configure_decoder(stream, pt, sample_rate, nchannels);
1055 	}
1056 
1057 	/*create the equalizer*/
1058 	if ((stream->features & AUDIO_STREAM_FEATURE_EQUALIZER) != 0){
1059 		stream->mic_equalizer = ms_factory_create_filter(stream->ms.factory, MS_EQUALIZER_ID);
1060 		stream->spk_equalizer = ms_factory_create_filter(stream->ms.factory, MS_EQUALIZER_ID);
1061 		if(stream->mic_equalizer) {
1062 			tmp = stream->mic_eq_active;
1063 			ms_filter_call_method(stream->mic_equalizer,MS_EQUALIZER_SET_ACTIVE,&tmp);
1064 			ms_filter_call_method(stream->mic_equalizer,MS_FILTER_SET_SAMPLE_RATE, &sample_rate);
1065 		}
1066 		if(stream->spk_equalizer) {
1067 			tmp = stream->spk_eq_active;
1068 			ms_filter_call_method(stream->spk_equalizer,MS_EQUALIZER_SET_ACTIVE,&tmp);
1069 			ms_filter_call_method(stream->spk_equalizer,MS_FILTER_SET_SAMPLE_RATE, &sample_rate);
1070 		}
1071 	}else {
1072 		stream->mic_equalizer=NULL;
1073 		stream->spk_equalizer=NULL;
1074 	}
1075 
1076 #ifdef __ANDROID__
1077 	{
1078 		/*configure equalizer if needed*/
1079 		MSDevicesInfo *devices = ms_factory_get_devices_info(stream->ms.factory);
1080 		SoundDeviceDescription *device = ms_devices_info_get_sound_device_description(devices);
1081 
1082 		audio_stream_set_mic_gain_db(stream, 0);
1083 		audio_stream_set_spk_gain_db(stream, 0);
1084 		if (device && device->hacks) {
1085 			const char *gains;
1086 			gains = device->hacks->mic_equalizer;
1087 			if (gains && stream->mic_equalizer) {
1088 				bctbx_list_t *gains_list = ms_parse_equalizer_string(gains);
1089 				if (gains_list) {
1090 					bctbx_list_t *it;
1091 					ms_message("Found equalizer configuration for the microphone in the devices table");
1092 					for (it = gains_list; it; it=it->next) {
1093 						MSEqualizerGain *g = (MSEqualizerGain *)it->data;
1094 						ms_message("Read equalizer gains: %f(~%f) --> %f", g->frequency, g->width, g->gain);
1095 						ms_filter_call_method(stream->mic_equalizer, MS_EQUALIZER_SET_GAIN, g);
1096 					}
1097 					bctbx_list_free_with_data(gains_list, ms_free);
1098 				}
1099 			}
1100 			gains = device->hacks->spk_equalizer;
1101 			if (gains && stream->spk_equalizer) {
1102 				bctbx_list_t *gains_list = ms_parse_equalizer_string(gains);
1103 				if (gains_list) {
1104 					bctbx_list_t *it;
1105 					ms_message("Found equalizer configuration for the speakers in the devices table");
1106 					for (it = gains_list; it; it=it->next) {
1107 						MSEqualizerGain *g = (MSEqualizerGain *)it->data;
1108 						ms_message("Read equalizer gains: %f(~%f) --> %f", g->frequency, g->width, g->gain);
1109 						ms_filter_call_method(stream->spk_equalizer, MS_EQUALIZER_SET_GAIN, g);
1110 					}
1111 					bctbx_list_free_with_data(gains_list, ms_free);
1112 				}
1113 			}
1114 		}
1115 	}
1116 #endif
1117 
1118 	/*configure resamplers if needed*/
1119 	if (stream->read_resampler) {
1120 		MSFilter *from = stream->soundread;
1121 		if (stream->read_decoder) from = stream->read_decoder;
1122 		audio_stream_configure_resampler(stream, stream->read_resampler, from, skip_encoder_and_decoder ? stream->soundread : stream->ms.encoder);
1123 	}
1124 	if (stream->write_resampler) {
1125 		MSFilter *to = stream->soundwrite;
1126 		if (stream->write_encoder) to = stream->write_encoder;
1127 		audio_stream_configure_resampler(stream, stream->write_resampler, skip_encoder_and_decoder ? stream->soundwrite : stream->ms.decoder, to);
1128 	}
1129 
1130 	if (stream->ms.rc_enable){
1131 		switch (stream->ms.rc_algorithm){
1132 		case MSQosAnalyzerAlgorithmSimple:
1133 			stream->ms.rc=ms_audio_bitrate_controller_new(stream->ms.sessions.rtp_session, skip_encoder_and_decoder ? stream->soundwrite : stream->ms.encoder, 0);
1134 			break;
1135 		case MSQosAnalyzerAlgorithmStateful:
1136 			stream->ms.rc=ms_bandwidth_bitrate_controller_new(stream->ms.sessions.rtp_session, skip_encoder_and_decoder ? stream->soundwrite : stream->ms.encoder, NULL, NULL);
1137 			break;
1138 		}
1139 	}
1140 
1141 	/* Create generic PLC if not handled by the decoder directly*/
1142 	if ((stream->features & AUDIO_STREAM_FEATURE_PLC) != 0) {
1143 		int decoder_have_plc = 0;
1144 		if (ms_filter_has_method(stream->ms.decoder, MS_AUDIO_DECODER_HAVE_PLC)) {
1145 			if (ms_filter_call_method(stream->ms.decoder, MS_AUDIO_DECODER_HAVE_PLC, &decoder_have_plc) != 0) {
1146 				ms_warning("MS_AUDIO_DECODER_HAVE_PLC function error: enable default plc");
1147 			}
1148 		} else {
1149 			ms_warning("MS_DECODER_HAVE_PLC function not implemented by the decoder: enable default plc");
1150 		}
1151 		if (decoder_have_plc == 0) {
1152 			stream->plc = ms_factory_create_filter(stream->ms.factory, MS_GENERIC_PLC_ID);
1153 
1154 			if (stream->plc) {
1155 				ms_filter_call_method(stream->plc, MS_FILTER_SET_NCHANNELS, &nchannels);
1156 				ms_filter_call_method(stream->plc, MS_FILTER_SET_SAMPLE_RATE, &sample_rate);
1157 				/*as first rough approximation, a codec without PLC capabilities has no VAD/DTX builtin, thus setup generic confort noise if possible*/
1158 				setup_generic_confort_noise(stream);
1159 			}
1160 
1161 		}
1162 	} else if (!skip_encoder_and_decoder) {
1163 		if (ms_filter_has_method(stream->ms.decoder, MS_DECODER_ENABLE_PLC)){
1164 			int decoder_enable_plc = 0;
1165 			if (ms_filter_call_method(stream->ms.decoder, MS_DECODER_ENABLE_PLC, &decoder_enable_plc) != 0) {
1166 				ms_warning(" MS_DECODER_ENABLE_PLC on stream %p function error ", stream);
1167 			}
1168 
1169 		}
1170 		stream->plc = NULL;
1171 	}
1172 
1173 	if ((stream->features & AUDIO_STREAM_FEATURE_FLOW_CONTROL) != 0) {
1174 		stream->flowcontrol = ms_factory_create_filter(stream->ms.factory, MS_AUDIO_FLOW_CONTROL_ID);
1175 		if (stream->flowcontrol) {
1176 			ms_filter_call_method(stream->flowcontrol, MS_FILTER_SET_NCHANNELS, &nchannels);
1177 			ms_filter_call_method(stream->flowcontrol, MS_FILTER_SET_SAMPLE_RATE, &sample_rate);
1178 			if (stream->ec) ms_filter_add_notify_callback(stream->ec, ms_audio_flow_control_event_handler, stream->flowcontrol, FALSE);
1179 			if (stream->soundwrite) ms_filter_add_notify_callback(stream->soundwrite, ms_audio_flow_control_event_handler, stream->flowcontrol, FALSE);
1180 		}
1181 	} else {
1182 		stream->flowcontrol = NULL;
1183 	}
1184 
1185 	if (stream->features & AUDIO_STREAM_FEATURE_LOCAL_PLAYING){
1186 		stream->local_mixer=ms_factory_create_filter(stream->ms.factory, MS_AUDIO_MIXER_ID);
1187 
1188 	}
1189 
1190 	if (stream->outbound_mixer){
1191 		ms_filter_call_method(stream->outbound_mixer,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
1192 		ms_filter_call_method(stream->outbound_mixer,MS_FILTER_SET_NCHANNELS,&nchannels);
1193 	}
1194 
1195 	/* create ticker */
1196 	if (stream->ms.sessions.ticker==NULL) media_stream_start_ticker(&stream->ms);
1197 
1198 	/* and then connect all */
1199 	/* tip: draw yourself the picture if you don't understand */
1200 
1201 	/*sending graph*/
1202 	ms_connection_helper_start(&h);
1203 	ms_connection_helper_link(&h,stream->soundread,-1,0);
1204 	if (stream->read_decoder)
1205 		ms_connection_helper_link(&h, stream->read_decoder, 0, 0);
1206 	if (stream->read_resampler)
1207 		ms_connection_helper_link(&h,stream->read_resampler,0,0);
1208 	if( stream->mic_equalizer)
1209 		ms_connection_helper_link(&h,stream->mic_equalizer, 0, 0);
1210 	if (stream->ec)
1211 		ms_connection_helper_link(&h,stream->ec,1,1);
1212 	if (stream->volsend)
1213 		ms_connection_helper_link(&h,stream->volsend,0,0);
1214 	if (stream->dtmfgen_rtp)
1215 		ms_connection_helper_link(&h,stream->dtmfgen_rtp,0,0);
1216 	if (stream->outbound_mixer)
1217 		ms_connection_helper_link(&h,stream->outbound_mixer,0,0);
1218 	if (stream->vaddtx)
1219 		ms_connection_helper_link(&h,stream->vaddtx,0,0);
1220 	if (!skip_encoder_and_decoder)
1221 		ms_connection_helper_link(&h,stream->ms.encoder,0,0);
1222 	ms_connection_helper_link(&h,stream->ms.rtpsend,0,-1);
1223 
1224 	/*receiving graph*/
1225 	ms_connection_helper_start(&h);
1226 	ms_connection_helper_link(&h,stream->ms.rtprecv,-1,0);
1227 	if (!skip_encoder_and_decoder)
1228 		ms_connection_helper_link(&h,stream->ms.decoder,0,0);
1229 	if (stream->plc)
1230 		ms_connection_helper_link(&h,stream->plc,0,0);
1231 	if (stream->flowcontrol)
1232 		ms_connection_helper_link(&h, stream->flowcontrol, 0, 0);
1233 	if (stream->dtmfgen)
1234 		ms_connection_helper_link(&h,stream->dtmfgen,0,0);
1235 	if (stream->volrecv)
1236 		ms_connection_helper_link(&h,stream->volrecv,0,0);
1237 	if (stream->recv_tee)
1238 		ms_connection_helper_link(&h,stream->recv_tee,0,0);
1239 	if (stream->spk_equalizer)
1240 		ms_connection_helper_link(&h,stream->spk_equalizer,0,0);
1241 	if (stream->local_mixer){
1242 		ms_connection_helper_link(&h,stream->local_mixer,0,0);
1243 		setup_local_player(stream,sample_rate, nchannels);
1244 	}
1245 	if (stream->ec)
1246 		ms_connection_helper_link(&h,stream->ec,0,0);
1247 	if (stream->write_resampler)
1248 		ms_connection_helper_link(&h,stream->write_resampler,0,0);
1249 	if (stream->write_encoder)
1250 		ms_connection_helper_link(&h, stream->write_encoder, 0, 0);
1251 	ms_connection_helper_link(&h,stream->soundwrite,0,-1);
1252 
1253 	/*call recording part, attached to both outgoing and incoming graphs*/
1254 	if (stream->av_recorder.recorder)
1255 		plumb_av_recorder(stream);
1256 	if (stream->recorder){
1257 		ms_filter_link(stream->outbound_mixer,1,stream->recorder_mixer,0);
1258 		ms_filter_link(stream->recv_tee,1,stream->recorder_mixer,1);
1259 		ms_filter_link(stream->recorder_mixer,0,stream->recorder,0);
1260 	}
1261 
1262 	/*to make sure all preprocess are done before befre processing audio*/
1263 	ms_ticker_attach_multiple(stream->ms.sessions.ticker
1264 				,stream->soundread
1265 				,stream->ms.rtprecv
1266 				,NULL);
1267 
1268 	stream->ms.start_time=stream->ms.last_packet_time=ms_time(NULL);
1269 	stream->ms.is_beginning=TRUE;
1270 	stream->ms.state=MSStreamStarted;
1271 
1272 	if (stream->soundwrite) {
1273 		if (ms_filter_implements_interface(stream->soundwrite, MSFilterAudioPlaybackInterface)) {
1274 			ms_filter_call_method(stream->soundwrite, MS_AUDIO_PLAYBACK_SET_ROUTE, &stream->audio_route);
1275 		}
1276 	}
1277 
1278 	return 0;
1279 }
1280 
audio_stream_start_full(AudioStream * stream,RtpProfile * profile,const char * rem_rtp_ip,int rem_rtp_port,const char * rem_rtcp_ip,int rem_rtcp_port,int payload,int jitt_comp,const char * infile,const char * outfile,MSSndCard * playcard,MSSndCard * captcard,bool_t use_ec)1281 int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char *rem_rtp_ip,int rem_rtp_port,
1282 	const char *rem_rtcp_ip, int rem_rtcp_port, int payload,int jitt_comp, const char *infile, const char *outfile,
1283 	MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec){
1284 	MSMediaStreamIO io = MS_MEDIA_STREAM_IO_INITIALIZER;
1285 
1286 	if (playcard){
1287 		io.output.type = MSResourceSoundcard;
1288 		io.output.soundcard = playcard;
1289 	}else{
1290 		io.output.type = MSResourceFile;
1291 		io.output.file = outfile;
1292 	}
1293 	if (captcard){
1294 		io.input.type = MSResourceSoundcard;
1295 		io.input.soundcard = captcard;
1296 	}else{
1297 		io.input.type = MSResourceFile;
1298 		io.input.file = infile;
1299 	}
1300 	if (jitt_comp != -1)
1301 		rtp_session_set_jitter_compensation(stream->ms.sessions.rtp_session, jitt_comp);
1302 	audio_stream_enable_echo_canceller(stream, use_ec);
1303 	return audio_stream_start_from_io(stream, profile, rem_rtp_ip, rem_rtp_port, rem_rtcp_ip, rem_rtcp_port, payload, &io);
1304 }
1305 
audio_stream_start_with_files(AudioStream * stream,RtpProfile * prof,const char * remip,int remport,int rem_rtcp_port,int pt,int jitt_comp,const char * infile,const char * outfile)1306 int audio_stream_start_with_files(AudioStream *stream, RtpProfile *prof,const char *remip, int remport,
1307 	int rem_rtcp_port, int pt,int jitt_comp, const char *infile, const char * outfile)
1308 {
1309 	return audio_stream_start_full(stream,prof,remip,remport,remip,rem_rtcp_port,pt,jitt_comp,infile,outfile,NULL,NULL,FALSE);
1310 }
1311 
audio_stream_start(MSFactory * factory,RtpProfile * prof,int locport,const char * remip,int remport,int profile,int jitt_comp,bool_t use_ec)1312 AudioStream *audio_stream_start(MSFactory* factory, RtpProfile *prof,int locport,const char *remip,int remport,int profile,int jitt_comp,bool_t use_ec)
1313 {
1314 	MSSndCard *sndcard_playback;
1315 	MSSndCard *sndcard_capture;
1316 	AudioStream *stream;
1317 	sndcard_capture=ms_snd_card_manager_get_default_capture_card(ms_factory_get_snd_card_manager(factory));
1318 	sndcard_playback=ms_snd_card_manager_get_default_playback_card(ms_factory_get_snd_card_manager(factory));
1319 	if (sndcard_capture==NULL || sndcard_playback==NULL)
1320 		return NULL;
1321 	stream=audio_stream_new(factory, locport, locport+1, ms_is_ipv6(remip));
1322 	if (audio_stream_start_full(stream,prof,remip,remport,remip,remport+1,profile,jitt_comp,NULL,NULL,sndcard_playback,sndcard_capture,use_ec)==0) return stream;
1323 	audio_stream_free(stream);
1324 	return NULL;
1325 }
1326 
audio_stream_start_with_sndcards(MSFactory * factory,RtpProfile * prof,int locport,const char * remip,int remport,int profile,int jitt_comp,MSSndCard * playcard,MSSndCard * captcard,bool_t use_ec)1327 AudioStream *audio_stream_start_with_sndcards(MSFactory* factory, RtpProfile *prof,int locport,const char *remip,int remport,int profile,int jitt_comp,MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec)
1328 {
1329 	AudioStream *stream;
1330 	if (playcard==NULL) {
1331 		ms_error("No playback card.");
1332 		return NULL;
1333 	}
1334 	if (captcard==NULL) {
1335 		ms_error("No capture card.");
1336 		return NULL;
1337 	}
1338 	stream=audio_stream_new(factory, locport, locport+1, ms_is_ipv6(remip));
1339 	if (audio_stream_start_full(stream,prof,remip,remport,remip,remport+1,profile,jitt_comp,NULL,NULL,playcard,captcard,use_ec)==0) return stream;
1340 	audio_stream_free(stream);
1341 	return NULL;
1342 }
1343 
1344 // Pass NULL to stop playing
audio_stream_play(AudioStream * st,const char * name)1345 void audio_stream_play(AudioStream *st, const char *name){
1346 	if (st->soundread == NULL) {
1347 		ms_warning("Cannot play file: the stream hasn't been started");
1348 		return;
1349 	}
1350 	if (ms_filter_get_id(st->soundread)==MS_FILE_PLAYER_ID){
1351 		ms_filter_call_method_noarg(st->soundread,MS_FILE_PLAYER_CLOSE);
1352 		if (name != NULL) {
1353 			ms_filter_call_method(st->soundread,MS_FILE_PLAYER_OPEN,(void*)name);
1354 			if (st->read_resampler){
1355 				audio_stream_configure_resampler(st, st->read_resampler,st->soundread,st->ms.encoder);
1356 			}
1357 			ms_filter_call_method_noarg(st->soundread,MS_FILE_PLAYER_START);
1358 		}
1359 	}else{
1360 		ms_error("Cannot play file: the stream hasn't been started with"
1361 		" audio_stream_start_with_files");
1362 	}
1363 }
1364 
audio_stream_get_local_player(AudioStream * st)1365 MSFilter * audio_stream_get_local_player(AudioStream *st) {
1366 	return st->local_player;
1367 }
1368 
audio_stream_record(AudioStream * st,const char * name)1369 void audio_stream_record(AudioStream *st, const char *name){
1370 	if (ms_filter_get_id(st->soundwrite)==MS_FILE_REC_ID){
1371 		ms_filter_call_method_noarg(st->soundwrite,MS_FILE_REC_CLOSE);
1372 		ms_filter_call_method(st->soundwrite,MS_FILE_REC_OPEN,(void*)name);
1373 		ms_filter_call_method_noarg(st->soundwrite,MS_FILE_REC_START);
1374 	}else{
1375 		ms_error("Cannot record file: the stream hasn't been started with"
1376 		" audio_stream_start_with_files");
1377 	}
1378 }
1379 
1380 
audio_stream_mixed_record_open(AudioStream * st,const char * filename)1381 int audio_stream_mixed_record_open(AudioStream *st, const char* filename){
1382 	if (!(st->features & AUDIO_STREAM_FEATURE_MIXED_RECORDING)){
1383 		if (audio_stream_started(st)){
1384 			ms_error("Too late - you cannot request a mixed recording when the stream is running because it did not have AUDIO_STREAM_FEATURE_MIXED_RECORDING feature.");
1385 			return -1;
1386 		}else{
1387 			st->features|=AUDIO_STREAM_FEATURE_MIXED_RECORDING;
1388 		}
1389 	}
1390 	if (st->recorder_file){
1391 		audio_stream_mixed_record_stop(st);
1392 	}
1393 	st->recorder_file=filename ? ms_strdup(filename) : NULL;
1394 	return 0;
1395 }
1396 
get_recorder(AudioStream * stream)1397 static MSFilter *get_recorder(AudioStream *stream){
1398 	const char *fname=stream->recorder_file;
1399 	size_t len=strlen(fname);
1400 
1401 	if (strstr(fname,".mkv")==fname+len-4){
1402 		if (stream->av_recorder.recorder){
1403 			return stream->av_recorder.recorder;
1404 		}else{
1405 			ms_error("Cannot record in mkv format, not supported in this build.");
1406 			return NULL;
1407 		}
1408 	}
1409 	return stream->recorder;
1410 }
1411 
audio_stream_mixed_record_start(AudioStream * st)1412 int audio_stream_mixed_record_start(AudioStream *st){
1413 	if (st->recorder && st->recorder_file){
1414 		int pin=1;
1415 		MSRecorderState state;
1416 		MSAudioMixerCtl mctl={0};
1417 		MSFilter *recorder=get_recorder(st);
1418 
1419 		if (recorder==NULL) return -1;
1420 		ms_filter_call_method(recorder,MS_RECORDER_GET_STATE,&state);
1421 		if (state==MSRecorderClosed){
1422 			if (ms_filter_call_method(recorder,MS_RECORDER_OPEN,st->recorder_file)==-1)
1423 				return -1;
1424 		}
1425 		ms_filter_call_method_noarg(recorder,MS_RECORDER_START);
1426 		ms_filter_call_method(st->recv_tee,MS_TEE_UNMUTE,&pin);
1427 		mctl.pin=pin;
1428 		mctl.param.enabled=TRUE;
1429 		ms_filter_call_method(st->outbound_mixer,MS_AUDIO_MIXER_ENABLE_OUTPUT,&mctl);
1430 		return 0;
1431 	}
1432 	return -1;
1433 }
1434 
audio_stream_mixed_record_stop(AudioStream * st)1435 int audio_stream_mixed_record_stop(AudioStream *st){
1436 	if (st->recorder && st->recorder_file){
1437 		int pin=1;
1438 		MSFilter *recorder=get_recorder(st);
1439 		MSAudioMixerCtl mctl={0};
1440 
1441 		if (recorder==NULL) return -1;
1442 		ms_filter_call_method(st->recv_tee,MS_TEE_MUTE,&pin);
1443 		mctl.pin=pin;
1444 		mctl.param.enabled=FALSE;
1445 		ms_filter_call_method(st->outbound_mixer,MS_AUDIO_MIXER_ENABLE_OUTPUT,&mctl);
1446 		ms_filter_call_method_noarg(recorder,MS_RECORDER_PAUSE);
1447 		ms_filter_call_method_noarg(recorder,MS_RECORDER_CLOSE);
1448 	}
1449 	return 0;
1450 }
1451 
audio_stream_get_features(AudioStream * st)1452 uint32_t audio_stream_get_features(AudioStream *st){
1453 	return st->features;
1454 }
1455 
audio_stream_set_features(AudioStream * st,uint32_t features)1456 void audio_stream_set_features(AudioStream *st, uint32_t features){
1457 	st->features = features;
1458 }
1459 
audio_stream_new_with_sessions(MSFactory * factory,const MSMediaStreamSessions * sessions)1460 AudioStream *audio_stream_new_with_sessions(MSFactory *factory, const MSMediaStreamSessions *sessions){
1461 	AudioStream *stream=(AudioStream *)ms_new0(AudioStream,1);
1462 	const char *echo_canceller_filtername = ms_factory_get_echo_canceller_filter_name(factory);
1463 	MSFilterDesc *ec_desc = NULL;
1464 	const OrtpRtcpXrMediaCallbacks rtcp_xr_media_cbs = {
1465 		audio_stream_get_rtcp_xr_plc_status,
1466 		audio_stream_get_rtcp_xr_signal_level,
1467 		audio_stream_get_rtcp_xr_noise_level,
1468 		audio_stream_get_rtcp_xr_average_quality_rating,
1469 		audio_stream_get_rtcp_xr_average_lq_quality_rating,
1470 		stream
1471 	};
1472 
1473 	if (echo_canceller_filtername != NULL) {
1474 		ec_desc = ms_factory_lookup_filter_by_name(factory, echo_canceller_filtername);
1475 	}
1476 
1477 	stream->ms.type = MSAudio;
1478 	media_stream_init(&stream->ms,factory, sessions);
1479 
1480 	ms_factory_enable_statistics(factory, TRUE);
1481 	ms_factory_reset_statistics(factory);
1482 
1483 	rtp_session_resync(stream->ms.sessions.rtp_session);
1484 	/*some filters are created right now to allow configuration by the application before start() */
1485 	stream->ms.rtpsend=ms_factory_create_filter(factory, MS_RTP_SEND_ID);
1486 	stream->ms.ice_check_list=NULL;
1487 	stream->ms.qi=ms_quality_indicator_new(stream->ms.sessions.rtp_session);
1488 	ms_quality_indicator_set_label(stream->ms.qi,"audio");
1489 	stream->ms.process_rtcp=audio_stream_process_rtcp;
1490 	if (ec_desc!=NULL){
1491 		stream->ec=ms_factory_create_filter_from_desc(factory, ec_desc);
1492 	}else{
1493 		stream->ec=ms_factory_create_filter(factory, MS_SPEEX_EC_ID );
1494 	}
1495 	stream->play_dtmfs=TRUE;
1496 	stream->use_gc=FALSE;
1497 	stream->use_agc=FALSE;
1498 	stream->use_ng=FALSE;
1499 	stream->features=AUDIO_STREAM_FEATURE_ALL;
1500 
1501 	rtp_session_set_rtcp_xr_media_callbacks(stream->ms.sessions.rtp_session, &rtcp_xr_media_cbs);
1502 
1503 	return stream;
1504 }
1505 
audio_stream_new(MSFactory * factory,int loc_rtp_port,int loc_rtcp_port,bool_t ipv6)1506 AudioStream *audio_stream_new(MSFactory* factory, int loc_rtp_port, int loc_rtcp_port, bool_t ipv6){
1507 	return audio_stream_new2(factory, ipv6 ? "::" : "0.0.0.0", loc_rtp_port, loc_rtcp_port);
1508 }
1509 
audio_stream_new2(MSFactory * factory,const char * ip,int loc_rtp_port,int loc_rtcp_port)1510 AudioStream *audio_stream_new2(MSFactory* factory, const char* ip, int loc_rtp_port, int loc_rtcp_port) {
1511 	AudioStream *obj;
1512 	MSMediaStreamSessions sessions={0};
1513 	sessions.rtp_session=ms_create_duplex_rtp_session(ip,loc_rtp_port,loc_rtcp_port, ms_factory_get_mtu(factory));
1514 	obj=audio_stream_new_with_sessions(factory, &sessions);
1515 	obj->ms.owns_sessions=TRUE;
1516 	return obj;
1517 }
1518 
audio_stream_play_received_dtmfs(AudioStream * st,bool_t yesno)1519 void audio_stream_play_received_dtmfs(AudioStream *st, bool_t yesno){
1520 	st->play_dtmfs=yesno;
1521 }
1522 
audio_stream_start_now(AudioStream * stream,RtpProfile * prof,const char * remip,int remport,int rem_rtcp_port,int payload_type,int jitt_comp,MSSndCard * playcard,MSSndCard * captcard,bool_t use_ec)1523 int audio_stream_start_now(AudioStream *stream, RtpProfile * prof,  const char *remip, int remport, int rem_rtcp_port, int payload_type, int jitt_comp, MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec){
1524 	return audio_stream_start_full(stream,prof,remip,remport,remip,rem_rtcp_port,
1525 		payload_type,jitt_comp,NULL,NULL,playcard,captcard,use_ec);
1526 }
1527 
audio_stream_set_relay_session_id(AudioStream * stream,const char * id)1528 void audio_stream_set_relay_session_id(AudioStream *stream, const char *id){
1529 	ms_filter_call_method(stream->ms.rtpsend, MS_RTP_SEND_SET_RELAY_SESSION_ID,(void*)id);
1530 }
1531 
audio_stream_enable_echo_canceller(AudioStream * st,bool_t enabled)1532 void audio_stream_enable_echo_canceller(AudioStream *st, bool_t enabled){
1533 	st->use_ec = enabled;
1534 }
1535 
audio_stream_set_echo_canceller_params(AudioStream * stream,int tail_len_ms,int delay_ms,int framesize)1536 void audio_stream_set_echo_canceller_params(AudioStream *stream, int tail_len_ms, int delay_ms, int framesize){
1537 	if (stream->ec){
1538 		if (tail_len_ms>0)
1539 			ms_filter_call_method(stream->ec,MS_ECHO_CANCELLER_SET_TAIL_LENGTH,&tail_len_ms);
1540 		if (delay_ms>0){
1541 			stream->is_ec_delay_set=TRUE;
1542 			ms_filter_call_method(stream->ec,MS_ECHO_CANCELLER_SET_DELAY,&delay_ms);
1543 		}
1544 		if (framesize>0)
1545 			ms_filter_call_method(stream->ec,MS_ECHO_CANCELLER_SET_FRAMESIZE,&framesize);
1546 	}
1547 }
1548 
audio_stream_enable_echo_limiter(AudioStream * stream,EchoLimiterType type)1549 void audio_stream_enable_echo_limiter(AudioStream *stream, EchoLimiterType type){
1550 	stream->el_type=type;
1551 	if (stream->volsend){
1552 		bool_t enable_noise_gate = stream->el_type==ELControlFull;
1553 		ms_filter_call_method(stream->volrecv,MS_VOLUME_ENABLE_NOISE_GATE,&enable_noise_gate);
1554 		ms_filter_call_method(stream->volsend,MS_VOLUME_SET_PEER,type!=ELInactive?stream->volrecv:NULL);
1555 	} else {
1556 		ms_warning("cannot set echo limiter to mode [%i] because no volume send",type);
1557 	}
1558 }
1559 
audio_stream_enable_gain_control(AudioStream * stream,bool_t val)1560 void audio_stream_enable_gain_control(AudioStream *stream, bool_t val){
1561 	stream->use_gc=val;
1562 }
1563 
audio_stream_enable_automatic_gain_control(AudioStream * stream,bool_t val)1564 void audio_stream_enable_automatic_gain_control(AudioStream *stream, bool_t val){
1565 	stream->use_agc=val;
1566 }
1567 
audio_stream_enable_noise_gate(AudioStream * stream,bool_t val)1568 void audio_stream_enable_noise_gate(AudioStream *stream, bool_t val){
1569 	stream->use_ng=val;
1570 	if (stream->volsend){
1571 		ms_filter_call_method(stream->volsend,MS_VOLUME_ENABLE_NOISE_GATE,&val);
1572 	} else {
1573 		ms_message("cannot set noise gate mode to [%i] because no volume send",val);
1574 	}
1575 }
1576 
audio_stream_set_mic_gain_db(AudioStream * stream,float gain_db)1577 void audio_stream_set_mic_gain_db(AudioStream *stream, float gain_db) {
1578 	audio_stream_set_rtp_output_gain_db(stream, gain_db);
1579 }
1580 
audio_stream_set_mic_gain(AudioStream * stream,float gain)1581 void audio_stream_set_mic_gain(AudioStream *stream, float gain){
1582 	if (stream->volsend){
1583 		ms_filter_call_method(stream->volsend,MS_VOLUME_SET_GAIN,&gain);
1584 	}else ms_warning("Could not apply gain: gain control wasn't activated. "
1585 			"Use audio_stream_enable_gain_control() before starting the stream.");
1586 }
1587 
audio_stream_set_sound_card_input_gain(AudioStream * stream,float volume)1588 void audio_stream_set_sound_card_input_gain(AudioStream *stream, float volume) {
1589 	if (stream->soundread) {
1590 		if(ms_filter_implements_interface(stream->soundread, MSFilterAudioCaptureInterface)) {
1591 			ms_filter_call_method(stream->soundread, MS_AUDIO_CAPTURE_SET_VOLUME_GAIN, &volume);
1592 		}
1593 	} else {
1594 		ms_error("Cannot set input volume: no input filter");
1595 	}
1596 }
1597 
audio_stream_get_sound_card_input_gain(const AudioStream * stream)1598 float audio_stream_get_sound_card_input_gain(const AudioStream *stream) {
1599 	float volume;
1600 
1601 	if(stream->soundread == NULL) {
1602 		ms_error("Cannot get input volume: no input filter");
1603 		return -1.0f;
1604 	}
1605 	if(!ms_filter_implements_interface(stream->soundread, MSFilterAudioCaptureInterface)) {
1606 		return -1.0f;
1607 	}
1608 	if(ms_filter_call_method(stream->soundread, MS_AUDIO_CAPTURE_GET_VOLUME_GAIN, &volume) < 0) {
1609 		volume = -1.0f;
1610 	}
1611 	return volume;
1612 }
1613 
audio_stream_set_sound_card_output_gain(AudioStream * stream,float volume)1614 void audio_stream_set_sound_card_output_gain(AudioStream *stream, float volume) {
1615 	if (stream->soundwrite) {
1616 		if(ms_filter_implements_interface(stream->soundwrite, MSFilterAudioPlaybackInterface)) {
1617 			ms_filter_call_method(stream->soundwrite, MS_AUDIO_PLAYBACK_SET_VOLUME_GAIN, &volume);
1618 		}
1619 	} else {
1620 		ms_error("Cannot set output volume: no output filter");
1621 	}
1622 }
1623 
audio_stream_get_sound_card_output_gain(const AudioStream * stream)1624 float audio_stream_get_sound_card_output_gain(const AudioStream *stream) {
1625 	float volume;
1626 
1627 	if(stream->soundwrite == NULL) {
1628 		ms_error("Cannot get output volume: no output filter");
1629 		return -1.0f;
1630 	}
1631 	if(!ms_filter_implements_interface(stream->soundwrite, MSFilterAudioPlaybackInterface)) {
1632 		return -1.0f;
1633 	}
1634 	if(ms_filter_call_method(stream->soundwrite, MS_AUDIO_PLAYBACK_GET_VOLUME_GAIN, &volume) < 0) {
1635 		volume = -1.0f;
1636 	}
1637 	return volume;
1638 }
1639 
audio_stream_enable_equalizer(AudioStream * stream,EqualizerLocation location,bool_t enabled)1640 void audio_stream_enable_equalizer(AudioStream *stream, EqualizerLocation location, bool_t enabled) {
1641 	switch(location) {
1642 		case MSEqualizerHP:
1643 			stream->spk_eq_active = enabled;
1644 			if (stream->spk_equalizer) {
1645 				int tmp = enabled;
1646 				ms_filter_call_method(stream->spk_equalizer, MS_EQUALIZER_SET_ACTIVE, &tmp);
1647 			}
1648 			break;
1649 		case MSEqualizerMic:
1650 			stream->mic_eq_active = enabled;
1651 			if (stream->mic_equalizer) {
1652 				int tmp = enabled;
1653 				ms_filter_call_method(stream->mic_equalizer, MS_EQUALIZER_SET_ACTIVE, &tmp);
1654 			}
1655 			break;
1656 		default:
1657 			ms_error("%s(): bad equalizer location [%d]", __FUNCTION__, location);
1658 			break;
1659 	}
1660 }
1661 
audio_stream_equalizer_set_gain(AudioStream * stream,EqualizerLocation location,const MSEqualizerGain * gain)1662 void audio_stream_equalizer_set_gain(AudioStream *stream, EqualizerLocation location, const MSEqualizerGain *gain){
1663 	switch(location) {
1664 		case MSEqualizerHP:
1665 			if (stream->spk_equalizer) {
1666 				MSEqualizerGain d;
1667 				d.frequency = gain->frequency;
1668 				d.gain = gain->gain;
1669 				d.width = gain->width;
1670 				ms_filter_call_method(stream->spk_equalizer, MS_EQUALIZER_SET_GAIN, &d);
1671 			}
1672 			break;
1673 		case MSEqualizerMic:
1674 			if (stream->mic_equalizer) {
1675 				MSEqualizerGain d;
1676 				d.frequency = gain->frequency;
1677 				d.gain = gain->gain;
1678 				d.width = gain->width;
1679 				ms_filter_call_method(stream->mic_equalizer, MS_EQUALIZER_SET_GAIN, &d);
1680 			}
1681 			break;
1682 		default:
1683 			ms_error("%s(): bad equalizer location [%d]", __FUNCTION__, location);
1684 			break;
1685 	}
1686 }
1687 
dismantle_local_player(AudioStream * stream)1688 static void dismantle_local_player(AudioStream *stream){
1689 	MSConnectionHelper cnx;
1690 	ms_connection_helper_start(&cnx);
1691 	ms_connection_helper_unlink(&cnx,stream->local_player,-1,0);
1692 	if (stream->local_player_resampler){
1693 		ms_connection_helper_unlink(&cnx,stream->local_player_resampler,0,0);
1694 	}
1695 	ms_connection_helper_unlink(&cnx,stream->local_mixer,1,-1);
1696 }
1697 
audio_stream_stop(AudioStream * stream)1698 void audio_stream_stop(AudioStream * stream){
1699 	MSEventQueue *evq;
1700 
1701 	if (stream->ms.sessions.ticker){
1702 		MSConnectionHelper h;
1703 
1704 		if (stream->ms.state==MSStreamPreparing){
1705 			audio_stream_unprepare_sound(stream);
1706 		}else if (stream->ms.state==MSStreamStarted){
1707 			stream->ms.state=MSStreamStopped;
1708 			ms_ticker_detach(stream->ms.sessions.ticker,stream->soundread);
1709 			ms_ticker_detach(stream->ms.sessions.ticker,stream->ms.rtprecv);
1710 
1711 			if (stream->ms.ice_check_list != NULL) {
1712 				ice_check_list_print_route(stream->ms.ice_check_list, "Audio session's route");
1713 				stream->ms.ice_check_list = NULL;
1714 			}
1715 			rtp_stats_display(rtp_session_get_stats(stream->ms.sessions.rtp_session),
1716 				"             AUDIO SESSION'S RTP STATISTICS                ");
1717 
1718 			/*dismantle the outgoing graph*/
1719 			ms_connection_helper_start(&h);
1720 			ms_connection_helper_unlink(&h,stream->soundread,-1,0);
1721 			if (stream->read_decoder != NULL)
1722 				ms_connection_helper_unlink(&h, stream->read_decoder, 0, 0);
1723 			if (stream->read_resampler!=NULL)
1724 				ms_connection_helper_unlink(&h,stream->read_resampler,0,0);
1725 			if( stream->mic_equalizer)
1726 				ms_connection_helper_unlink(&h, stream->mic_equalizer, 0,0);
1727 			if (stream->ec!=NULL)
1728 				ms_connection_helper_unlink(&h,stream->ec,1,1);
1729 			if (stream->volsend!=NULL)
1730 				ms_connection_helper_unlink(&h,stream->volsend,0,0);
1731 			if (stream->dtmfgen_rtp)
1732 				ms_connection_helper_unlink(&h,stream->dtmfgen_rtp,0,0);
1733 			if (stream->outbound_mixer)
1734 				ms_connection_helper_unlink(&h,stream->outbound_mixer,0,0);
1735 			if (stream->vaddtx)
1736 				ms_connection_helper_unlink(&h,stream->vaddtx,0,0);
1737 			if (stream->ms.encoder)
1738 				ms_connection_helper_unlink(&h,stream->ms.encoder,0,0);
1739 			ms_connection_helper_unlink(&h,stream->ms.rtpsend,0,-1);
1740 
1741 			/*dismantle the receiving graph*/
1742 			ms_connection_helper_start(&h);
1743 			ms_connection_helper_unlink(&h,stream->ms.rtprecv,-1,0);
1744 			if (stream->ms.decoder)
1745 				ms_connection_helper_unlink(&h,stream->ms.decoder,0,0);
1746 			if (stream->plc!=NULL)
1747 				ms_connection_helper_unlink(&h,stream->plc,0,0);
1748 			if (stream->flowcontrol != NULL)
1749 				ms_connection_helper_unlink(&h, stream->flowcontrol, 0, 0);
1750 			if (stream->dtmfgen!=NULL)
1751 				ms_connection_helper_unlink(&h,stream->dtmfgen,0,0);
1752 			if (stream->volrecv!=NULL)
1753 				ms_connection_helper_unlink(&h,stream->volrecv,0,0);
1754 			if (stream->recv_tee)
1755 				ms_connection_helper_unlink(&h,stream->recv_tee,0,0);
1756 			if (stream->spk_equalizer!=NULL)
1757 				ms_connection_helper_unlink(&h,stream->spk_equalizer,0,0);
1758 			if (stream->local_mixer){
1759 				ms_connection_helper_unlink(&h,stream->local_mixer,0,0);
1760 				dismantle_local_player(stream);
1761 			}
1762 			if (stream->ec!=NULL)
1763 				ms_connection_helper_unlink(&h,stream->ec,0,0);
1764 			if (stream->write_resampler!=NULL)
1765 				ms_connection_helper_unlink(&h,stream->write_resampler,0,0);
1766 			if (stream->write_encoder != NULL)
1767 				ms_connection_helper_unlink(&h, stream->write_encoder, 0, 0);
1768 			ms_connection_helper_unlink(&h,stream->soundwrite,0,-1);
1769 
1770 			/*dismantle the call recording */
1771 			if (stream->av_recorder.recorder)
1772 				unplumb_av_recorder(stream);
1773 			if (stream->recorder){
1774 				ms_filter_unlink(stream->outbound_mixer,1,stream->recorder_mixer,0);
1775 				ms_filter_unlink(stream->recv_tee,1,stream->recorder_mixer,1);
1776 				ms_filter_unlink(stream->recorder_mixer,0,stream->recorder,0);
1777 			}
1778 			/*dismantle the remote play part*/
1779 			close_av_player(stream);
1780 		}
1781 	}
1782 	rtp_session_set_rtcp_xr_media_callbacks(stream->ms.sessions.rtp_session, NULL);
1783 	rtp_session_signal_disconnect_by_callback(stream->ms.sessions.rtp_session,"telephone-event",(RtpCallback)on_dtmf_received);
1784 	rtp_session_signal_disconnect_by_callback(stream->ms.sessions.rtp_session,"payload_type_changed",(RtpCallback)audio_stream_payload_type_changed);
1785 	/*before destroying the filters, pump the event queue so that pending events have a chance to reach their listeners.
1786 	 * When the filter are destroyed, all their pending events in the event queue will be cancelled*/
1787 	evq = ms_factory_get_event_queue(stream->ms.factory);
1788 	if (evq) ms_event_queue_pump(evq);
1789 	ms_factory_log_statistics(stream->ms.factory);
1790 	audio_stream_free(stream);
1791 
1792 //	ms_filter_log_statistics();
1793 }
1794 
audio_stream_send_dtmf(AudioStream * stream,char dtmf)1795 int audio_stream_send_dtmf(AudioStream *stream, char dtmf)
1796 {
1797 	if (stream->dtmfgen_rtp)
1798 		ms_filter_call_method(stream->dtmfgen_rtp,MS_DTMF_GEN_PLAY,&dtmf);
1799 	else if (stream->ms.rtpsend)
1800 		ms_filter_call_method(stream->ms.rtpsend,MS_RTP_SEND_SEND_DTMF,&dtmf);
1801 	return 0;
1802 }
1803 
audio_stream_set_rtp_output_gain_db(AudioStream * stream,float gain_db)1804 static void audio_stream_set_rtp_output_gain_db(AudioStream *stream, float gain_db) {
1805 	float gain = gain_db;
1806 #ifdef __ANDROID__
1807 	MSDevicesInfo *devices = ms_factory_get_devices_info(stream->ms.factory);
1808 	SoundDeviceDescription *device = ms_devices_info_get_sound_device_description(devices);
1809 	if (device && device->hacks) {
1810 		gain += device->hacks->mic_gain;
1811 		ms_message("Applying %f db to mic gain based on parameter and audio hack value in device table", gain);
1812 	}
1813 #endif
1814 
1815 	if (stream->volsend){
1816 		ms_filter_call_method(stream->volsend, MS_VOLUME_SET_DB_GAIN, &gain);
1817 	} else ms_warning("Could not apply gain on sent RTP packets: gain control wasn't activated. "
1818 			"Use audio_stream_enable_gain_control() before starting the stream.");
1819 }
1820 
audio_stream_mute_rtp(AudioStream * stream,bool_t val)1821 void audio_stream_mute_rtp(AudioStream *stream, bool_t val)
1822 {
1823 	if (stream->ms.rtpsend){
1824 		if (val)
1825 			ms_filter_call_method(stream->ms.rtpsend,MS_RTP_SEND_MUTE,&val);
1826 		else
1827 			ms_filter_call_method(stream->ms.rtpsend,MS_RTP_SEND_UNMUTE,&val);
1828 	}
1829 }
1830 
audio_stream_set_spk_gain_db(AudioStream * stream,float gain_db)1831 void audio_stream_set_spk_gain_db(AudioStream *stream, float gain_db) {
1832 	float gain = gain_db;
1833 #ifdef __ANDROID__
1834 	MSDevicesInfo *devices = ms_factory_get_devices_info(stream->ms.factory);
1835 	SoundDeviceDescription *device = ms_devices_info_get_sound_device_description(devices);
1836 	if (device && device->hacks) {
1837 		gain += device->hacks->spk_gain;
1838 		ms_message("Applying %f dB to speaker gain based on parameter and audio hack value in device table", gain);
1839 	}
1840 #endif
1841 
1842 	if (stream->volrecv){
1843 		ms_filter_call_method(stream->volrecv, MS_VOLUME_SET_DB_GAIN, &gain);
1844 	} else ms_warning("Could not apply gain on received RTP packet: gain control wasn't activated. "
1845 			"Use audio_stream_enable_gain_control() before starting the stream.");
1846 }
1847 
audio_stream_get_quality_rating(AudioStream * stream)1848 float audio_stream_get_quality_rating(AudioStream *stream){
1849 	return media_stream_get_quality_rating(&stream->ms);
1850 }
1851 
audio_stream_get_average_quality_rating(AudioStream * stream)1852 float audio_stream_get_average_quality_rating(AudioStream *stream){
1853 	return media_stream_get_average_quality_rating(&stream->ms);
1854 }
1855 
audio_stream_get_lq_quality_rating(AudioStream * stream)1856 float audio_stream_get_lq_quality_rating(AudioStream *stream) {
1857 	return media_stream_get_lq_quality_rating(&stream->ms);
1858 }
1859 
audio_stream_get_average_lq_quality_rating(AudioStream * stream)1860 float audio_stream_get_average_lq_quality_rating(AudioStream *stream) {
1861 	return media_stream_get_average_lq_quality_rating(&stream->ms);
1862 }
1863 
audio_stream_enable_zrtp(AudioStream * stream,MSZrtpParams * params)1864 void audio_stream_enable_zrtp(AudioStream *stream, MSZrtpParams *params){
1865 	if (stream->ms.sessions.zrtp_context==NULL)
1866 		stream->ms.sessions.zrtp_context=ms_zrtp_context_new( &(stream->ms.sessions), params);
1867 	else if (!media_stream_secured(&stream->ms))
1868 		ms_zrtp_reset_transmition_timer(stream->ms.sessions.zrtp_context);
1869 }
1870 
audio_stream_start_zrtp(AudioStream * stream)1871 void audio_stream_start_zrtp(AudioStream *stream) {
1872 	if (stream->ms.sessions.zrtp_context!=NULL) {
1873 		if (ms_zrtp_channel_start(stream->ms.sessions.zrtp_context) == MSZRTP_ERROR_CHANNEL_ALREADY_STARTED) {
1874 			ms_zrtp_reset_transmition_timer(stream->ms.sessions.zrtp_context);
1875 		}
1876 	} else {
1877 		ms_warning("Trying to start a ZRTP channel on audiostream, but none was enabled");
1878 	}
1879 }
1880 
audio_stream_zrtp_enabled(const AudioStream * stream)1881 bool_t audio_stream_zrtp_enabled(const AudioStream *stream) {
1882 	return stream->ms.sessions.zrtp_context!=NULL;
1883 }
1884 
configure_av_recorder(AudioStream * stream)1885 static void configure_av_recorder(AudioStream *stream){
1886 	if (stream->av_recorder.video_input && stream->av_recorder.recorder){
1887 		MSPinFormat pinfmt={0};
1888 		ms_filter_call_method(stream->av_recorder.video_input,MS_FILTER_GET_OUTPUT_FMT,&pinfmt);
1889 		if (pinfmt.fmt){
1890 			ms_message("Configuring av recorder with video format %s",ms_fmt_descriptor_to_string(pinfmt.fmt));
1891 			pinfmt.pin=0;
1892 			ms_filter_call_method(stream->av_recorder.recorder,MS_FILTER_SET_INPUT_FMT,&pinfmt);
1893 		}
1894 	}
1895 }
1896 
audio_stream_link_video(AudioStream * stream,VideoStream * video)1897 void audio_stream_link_video(AudioStream *stream, VideoStream *video){
1898 	stream->videostream=video;
1899 	if (stream->av_recorder.video_input && video->recorder_output){
1900 		ms_message("audio_stream_link_video() connecting itc filters");
1901 		ms_filter_call_method(video->recorder_output,MS_ITC_SINK_CONNECT,stream->av_recorder.video_input);
1902 		configure_av_recorder(stream);
1903 	}
1904 }
1905 
audio_stream_unlink_video(AudioStream * stream,VideoStream * video)1906 void audio_stream_unlink_video(AudioStream *stream, VideoStream *video){
1907 	stream->videostream=NULL;
1908 	if (stream->av_recorder.video_input && video->recorder_output){
1909 		ms_filter_call_method(video->recorder_output,MS_ITC_SINK_CONNECT,NULL);
1910 	}
1911 }
1912 
audio_stream_set_audio_route(AudioStream * stream,MSAudioRoute route)1913 void audio_stream_set_audio_route(AudioStream *stream, MSAudioRoute route) {
1914 	stream->audio_route = route;
1915 	if (stream->soundwrite) {
1916 		if (ms_filter_implements_interface(stream->soundwrite, MSFilterAudioPlaybackInterface)) {
1917 			ms_filter_call_method(stream->soundwrite, MS_AUDIO_PLAYBACK_SET_ROUTE, &route);
1918 		}
1919 	}
1920 }
1921 
1922