diff --git a/linphone/mediastreamer2/configure.ac b/linphone/mediastreamer2/configure.ac index be4fbc572..a9926ef0c 100644 --- a/linphone/mediastreamer2/configure.ac +++ b/linphone/mediastreamer2/configure.ac @@ -44,7 +44,7 @@ AC_MSG_CHECKING([warning make an error on compilation]) AC_ARG_ENABLE(strict, [ --enable-strict Enable error on compilation warning [default=no]], [wall_werror=$enableval], -[wall_werror=no] +[wall_werror=yes] ) CFLAGS="-DORTP_INET6 $CFLAGS " diff --git a/linphone/mediastreamer2/include/mediastreamer2/mediastream.h b/linphone/mediastreamer2/include/mediastreamer2/mediastream.h index 46507d4d5..5c575f73f 100644 --- a/linphone/mediastreamer2/include/mediastreamer2/mediastream.h +++ b/linphone/mediastreamer2/include/mediastreamer2/mediastream.h @@ -41,9 +41,11 @@ struct _AudioStream MSFilter *rtpsend; MSFilter *dtmfgen; MSFilter *ec;/*echo canceler*/ + MSFilter *volsend,*volrecv; /*MSVolumes*/ unsigned int last_packet_count; time_t last_packet_time; bool_t play_dtmfs; + bool_t use_ea; /*use echo avoider: two MSVolume, measured input level controlling local output level*/ }; #ifdef __cplusplus @@ -90,6 +92,9 @@ void audio_stream_set_relay_session_id(AudioStream *stream, const char *relay_se /*returns true if we are still receiving some data from remote end in the last timeout seconds*/ bool_t audio_stream_alive(AudioStream * stream, int timeout); +/*enable echo-avoider dispositve: one MSVolume in input branch controls a MSVolume in the output branch*/ +void audio_stream_enable_echo_avoider(AudioStream *stream, bool_t enabled); + /* stop the above process*/ void audio_stream_stop (AudioStream * stream); diff --git a/linphone/mediastreamer2/include/mediastreamer2/msfilter.h b/linphone/mediastreamer2/include/mediastreamer2/msfilter.h index 0e77ee023..b60544d9b 100644 --- a/linphone/mediastreamer2/include/mediastreamer2/msfilter.h +++ b/linphone/mediastreamer2/include/mediastreamer2/msfilter.h @@ -134,13 +134,33 @@ struct _MSFilter{ }; - /** * Structure to create/link/unlink/destroy filter's object. * @var MSFilter */ typedef struct _MSFilter MSFilter; +struct _MSConnectionPoint{ + MSFilter *filter; + int pin; +}; + +/** + * Structure that represents a connection point of a MSFilter + * @var MSConnectionPoint + */ +typedef struct _MSConnectionPoint MSConnectionPoint; + +struct _MSConnectionHelper{ + MSConnectionPoint last; +}; + +/** + * Structure that holds data when using the ms_connection_helper_* functions. + * @var MSConnectionHelper +**/ +typedef struct _MSConnectionHelper MSConnectionHelper; + #ifdef __cplusplus extern "C"{ @@ -275,7 +295,7 @@ MSFilter *ms_filter_new_from_desc(MSFilterDesc *desc); * @param f2 A MSFilter object containing the INPUT pin * @param pin2 An index of an INPUT pin. * - * Returns: a MSFilter if successfull, NULL otherwise. + * Returns: 0 if sucessful, -1 otherwise. */ int ms_filter_link(MSFilter *f1, int pin1, MSFilter *f2, int pin2); @@ -287,7 +307,7 @@ int ms_filter_link(MSFilter *f1, int pin1, MSFilter *f2, int pin2); * @param f2 A MSFilter object containing the INPUT pin * @param pin2 An index of an INPUT pin. * - * Returns: a MSFilter if successfull, NULL otherwise. + * Returns: 0 if sucessful, -1 otherwise. */ int ms_filter_unlink(MSFilter *f1, int pin1, MSFilter *f2, int pin2); @@ -340,6 +360,60 @@ MSFilterId ms_filter_get_id(MSFilter *f); */ void ms_filter_destroy(MSFilter *f); +/** + * Initialize a MSConnectionHelper. + * + * @param h A MSConnectionHelper, usually (but not necessarily) on stack + * +**/ +void ms_connection_helper_start(MSConnectionHelper *h); + +/** + * \brief Enter a MSFilter to be connected into the MSConnectionHelper object. + * + * This functions enters a MSFilter to be connected into the MSConnectionHelper + * object and connects it to the last entered if not the first one. + * The MSConnectionHelper is useful to reduce the amount of code necessary to create graphs in case + * the connections are made in an ordered manner and some filters are present conditionally in graphs. + * For example, instead of writing + * \code + * ms_filter_link(f1,0,f2,1); + * ms_filter_link(f2,0,f3,0); + * ms_filter_link(f3,1,f4,0); + * \endcode + * You can write: + * \code + * MSConnectionHelper h; + * ms_connection_helper_start(&h); + * ms_connection_helper_link(&h,f1,-1,0); + * ms_connection_helper_link(&h,f2,1,0); + * ms_connection_helper_link(&h,f3,0,1); + * ms_connection_helper_link(&h,f4,0,-1); + * \endcode + * Which is a bit longer to write here, but now imagine f2 needs to be present in the graph only + * in certain conditions: in the first case you have rewrite the two first lines, in the second case + * you just need to replace the fourth line by: + * \code + * if (my_condition) ms_connection_helper_link(&h,f2,1,0); + * \endcode + * + * @param h a connection helper + * @param f a MSFilter + * @param inpin an input pin number with which the MSFilter needs to connect to previously entered MSFilter + * @param outpin an output pin number with which the MSFilter needs to be connected to the next entered MSFilter + * + * Returns: the return value of ms_filter_link() that is called internally to this function. +**/ +int ms_connection_helper_link(MSConnectionHelper *h, MSFilter *f, int inpin, int outpin); + + +/** + * \brief Enter a MSFilter to be disconnected into the MSConnectionHelper object. + * Process exactly the same way as ms_connection_helper_link() but calls ms_filter_unlink() on the + * entered filters. +**/ +int ms_connection_helper_unlink(MSConnectionHelper *h, MSFilter *f, int inpin, int outpin); + /* I define the id taking the lower bits of the address of the MSFilterDesc object, the method index (_cnt_) and the argument size */ /* I hope using this to avoid type mismatch (calling a method on the wrong filter)*/ @@ -365,7 +439,7 @@ the method index (_cnt_) and the argument size */ #define MS_FILTER_EVENT_NO_ARG(_id_,_count_)\ MS_FILTER_METHOD_ID(_id_,_count_,0) -/* some MSFilter base methods:*/ +/* some MSFilter base generic methods:*/ #define MS_FILTER_SET_SAMPLE_RATE MS_FILTER_BASE_METHOD(0,int) #define MS_FILTER_GET_SAMPLE_RATE MS_FILTER_BASE_METHOD(1,int) #define MS_FILTER_SET_BITRATE MS_FILTER_BASE_METHOD(2,int) @@ -377,6 +451,8 @@ the method index (_cnt_) and the argument size */ #define MS_FILTER_SET_MTU MS_FILTER_BASE_METHOD(9,int) #define MS_FILTER_GET_MTU MS_FILTER_BASE_METHOD(10,int) + +/* more specific methods: to be moved into implementation specific header files*/ #define MS_FILTER_SET_FRAMESIZE MS_FILTER_BASE_METHOD(11,int) #define MS_FILTER_SET_FILTERLENGTH MS_FILTER_BASE_METHOD(12,int) #define MS_FILTER_SET_OUTPUT_SAMPLE_RATE MS_FILTER_BASE_METHOD(13,int) diff --git a/linphone/mediastreamer2/src/audiostream.c b/linphone/mediastreamer2/src/audiostream.c index 5301d8b22..2d86677e8 100644 --- a/linphone/mediastreamer2/src/audiostream.c +++ b/linphone/mediastreamer2/src/audiostream.c @@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/msrtp.h" #include "mediastreamer2/msfileplayer.h" #include "mediastreamer2/msfilerec.h" +#include "mediastreamer2/msvolume.h" #ifdef INET6 #include @@ -54,6 +55,8 @@ void audio_stream_free(AudioStream *stream) if (stream->decoder!=NULL) ms_filter_destroy(stream->decoder); if (stream->dtmfgen!=NULL) ms_filter_destroy(stream->dtmfgen); if (stream->ec!=NULL) ms_filter_destroy(stream->ec); + if (stream->volrecv!=NULL) ms_filter_destroy(stream->volrecv); + if (stream->volsend!=NULL) ms_filter_destroy(stream->volsend); if (stream->ticker!=NULL) ms_ticker_destroy(stream->ticker); ms_free(stream); } @@ -195,7 +198,8 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char { RtpSession *rtps=stream->session; PayloadType *pt; - int tmp; + int tmp; + MSConnectionHelper h; rtp_session_set_profile(rtps,profile); if (remport>0) rtp_session_set_remote_addr_full(rtps,remip,remport,rem_rtcp_port); @@ -241,7 +245,13 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char if (use_ec) { stream->ec=ms_filter_new(MS_SPEEX_EC_ID); ms_filter_call_method(stream->ec,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate); - } + } + + if (stream->use_ea){ + stream->volsend=ms_filter_new(MS_VOLUME_ID); + stream->volrecv=ms_filter_new(MS_VOLUME_ID); + ms_filter_call_method(stream->volrecv,MS_VOLUME_SET_PEER,stream->volsend); + } /* give the sound filters some properties */ ms_filter_call_method(stream->soundread,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate); @@ -263,19 +273,27 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char /* and then connect all */ /* tip: draw yourself the picture if you don't understand */ - if (stream->ec){ - ms_filter_link(stream->soundread,0,stream->ec,1); - ms_filter_link(stream->ec,1,stream->encoder,0); - ms_filter_link(stream->dtmfgen,0,stream->ec,0); - ms_filter_link(stream->ec,0,stream->soundwrite,0); - }else{ - ms_filter_link(stream->soundread,0,stream->encoder,0); - ms_filter_link(stream->dtmfgen,0,stream->soundwrite,0); - } - ms_filter_link(stream->encoder,0,stream->rtpsend,0); - ms_filter_link(stream->rtprecv,0,stream->decoder,0); - ms_filter_link(stream->decoder,0,stream->dtmfgen,0); + /*sending graph*/ + ms_connection_helper_start(&h); + ms_connection_helper_link(&h,stream->soundread,-1,0); + if (stream->ec) + ms_connection_helper_link(&h,stream->ec,1,1); + if (stream->volsend) + ms_connection_helper_link(&h,stream->volsend,0,0); + ms_connection_helper_link(&h,stream->encoder,0,0); + ms_connection_helper_link(&h,stream->rtpsend,0,-1); + + /*receiving graph*/ + ms_connection_helper_start(&h); + ms_connection_helper_link(&h,stream->rtprecv,-1,0); + ms_connection_helper_link(&h,stream->decoder,0,0); + ms_connection_helper_link(&h,stream->dtmfgen,0,0); + if (stream->volrecv) + ms_connection_helper_link(&h,stream->volrecv,0,0); + if (stream->ec) + ms_connection_helper_link(&h,stream->ec,0,0); + ms_connection_helper_link(&h,stream->soundwrite,0,-1); /* create ticker */ stream->ticker=ms_ticker_new(); @@ -375,27 +393,40 @@ void audio_stream_set_relay_session_id(AudioStream *stream, const char *id){ ms_filter_call_method(stream->rtpsend, MS_RTP_SEND_SET_RELAY_SESSION_ID,(void*)id); } +void audio_stream_enable_echo_avoider(AudioStream *stream, bool_t enabled){ + stream->use_ea=enabled; +} + void audio_stream_stop(AudioStream * stream) { if (stream->ticker){ + MSConnectionHelper h; ms_ticker_detach(stream->ticker,stream->soundread); ms_ticker_detach(stream->ticker,stream->rtprecv); rtp_stats_display(rtp_session_get_stats(stream->session),"Audio session's RTP statistics"); - if (stream->ec!=NULL){ - ms_filter_unlink(stream->soundread,0,stream->ec,1); - ms_filter_unlink(stream->ec,1,stream->encoder,0); - ms_filter_unlink(stream->dtmfgen,0,stream->ec,0); - ms_filter_unlink(stream->ec,0,stream->soundwrite,0); - }else{ - ms_filter_unlink(stream->soundread,0,stream->encoder,0); - ms_filter_unlink(stream->dtmfgen,0,stream->soundwrite,0); - } - - ms_filter_unlink(stream->encoder,0,stream->rtpsend,0); - ms_filter_unlink(stream->rtprecv,0,stream->decoder,0); - ms_filter_unlink(stream->decoder,0,stream->dtmfgen,0); + /*dismantle the outgoing graph*/ + ms_connection_helper_start(&h); + ms_connection_helper_unlink(&h,stream->soundread,-1,0); + if (stream->ec!=NULL) + ms_connection_helper_unlink(&h,stream->ec,1,1); + if (stream->volsend!=NULL) + ms_connection_helper_unlink(&h,stream->volsend,0,0); + ms_connection_helper_unlink(&h,stream->encoder,0,0); + ms_connection_helper_unlink(&h,stream->rtpsend,0,-1); + + /*dismantle the receiving graph*/ + ms_connection_helper_start(&h); + ms_connection_helper_unlink(&h,stream->rtprecv,-1,0); + ms_connection_helper_unlink(&h,stream->decoder,0,0); + ms_connection_helper_unlink(&h,stream->dtmfgen,0,0); + if (stream->volrecv!=NULL) + ms_connection_helper_unlink(&h,stream->volrecv,0,0); + if (stream->ec!=NULL) + ms_connection_helper_unlink(&h,stream->ec,0,0); + ms_connection_helper_unlink(&h,stream->soundwrite,0,-1); + } audio_stream_free(stream); } diff --git a/linphone/mediastreamer2/src/ice.c b/linphone/mediastreamer2/src/ice.c index c74b0bb5d..27da8a6cf 100644 --- a/linphone/mediastreamer2/src/ice.c +++ b/linphone/mediastreamer2/src/ice.c @@ -413,6 +413,7 @@ static int ice_sound_send_stun_request(RtpSession *session, struct IceCheckList return 0; } +#if 0 static int _ice_get_localip_for (struct sockaddr_storage *saddr, size_t saddr_len, char *loc, int size) { @@ -460,6 +461,8 @@ _ice_get_localip_for (struct sockaddr_storage *saddr, size_t saddr_len, char *lo return 0; } +#endif + static void _ice_createErrorResponse(StunMessage *response, int cl, int number, const char* msg) { diff --git a/linphone/mediastreamer2/src/msconf.c b/linphone/mediastreamer2/src/msconf.c index 792f4690c..03c8201a5 100644 --- a/linphone/mediastreamer2/src/msconf.c +++ b/linphone/mediastreamer2/src/msconf.c @@ -17,6 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #ifdef HAVE_CONFIG_H #include "mediastreamer-config.h" #endif @@ -93,8 +94,10 @@ typedef struct ConfState{ static void channel_init(ConfState *s, Channel *chan, int pos){ +#ifndef DISABLE_SPEEX float f; int val; +#endif memset(chan, 0, sizeof(Channel)); ms_bufferizer_init(&chan->buff); #ifndef DISABLE_SPEEX @@ -256,8 +259,7 @@ static bool_t should_process(MSFilter *f, ConfState *s){ } #ifndef DISABLE_SPEEX -static double powerspectrum_stat_beyond8K(struct Channel *chan) -{ +static double powerspectrum_stat_beyond8K(struct Channel *chan){ spx_int32_t ps_size = 0; spx_int32_t *ps = NULL; double mystat = 0; @@ -340,7 +342,6 @@ static void conf_sum(MSFilter *f, ConfState *s){ #if 0 int loudness; #endif - int vad=0; while (ms_bufferizer_get_avail(&chan->buff)> (ms_bufferizer_get_avail(&s->channels[0].buff)) ) { ms_bufferizer_read(&chan->buff,(uint8_t*)chan->input,s->conf_gran); @@ -351,6 +352,7 @@ static void conf_sum(MSFilter *f, ConfState *s){ #ifndef DISABLE_SPEEX if (chan->speex_pp!=NULL && s->enable_vad==TRUE) { + int vad=0; vad = speex_preprocess(chan->speex_pp, (short*)chan->input, NULL); if (vad==1) break; /* voice detected: process as usual */ diff --git a/linphone/mediastreamer2/src/msfilter.c b/linphone/mediastreamer2/src/msfilter.c index aa448216f..3711bed89 100644 --- a/linphone/mediastreamer2/src/msfilter.c +++ b/linphone/mediastreamer2/src/msfilter.c @@ -231,3 +231,40 @@ void ms_filter_notify_no_arg(MSFilter *f, unsigned int id){ if (f->notify!=NULL) f->notify(f->notify_ud,id,NULL); } + +void ms_connection_helper_start(MSConnectionHelper *h){ + h->last.filter=0; + h->last.pin=-1; +} + +int ms_connection_helper_link(MSConnectionHelper *h, MSFilter *f, int inpin, int outpin){ + int err=0; + if (h->last.filter==NULL){ + h->last.filter=f; + h->last.pin=outpin; + }else{ + err=ms_filter_link(h->last.filter,h->last.pin,f,inpin); + if (err==0){ + h->last.filter=f; + h->last.pin=outpin; + } + } + return err; +} + +int ms_connection_helper_unlink(MSConnectionHelper *h, MSFilter *f, int inpin, int outpin){ + int err=0; + if (h->last.filter==NULL){ + h->last.filter=f; + h->last.pin=outpin; + }else{ + err=ms_filter_unlink(h->last.filter,h->last.pin,f,inpin); + if (err==0){ + h->last.filter=f; + h->last.pin=outpin; + } + } + return err; +} + + diff --git a/linphone/mediastreamer2/src/msrtp.c b/linphone/mediastreamer2/src/msrtp.c index 804698e96..3debd9b7b 100644 --- a/linphone/mediastreamer2/src/msrtp.c +++ b/linphone/mediastreamer2/src/msrtp.c @@ -267,21 +267,18 @@ typedef struct ReceiverData ReceiverData; static void receiver_init(MSFilter * f) { ReceiverData *d = (ReceiverData *)ms_new(ReceiverData, 1); - d->session = NULL; d->rate = 8000; f->data = d; } -static void receiver_postprocess(MSFilter * f) -{ - ReceiverData *d = (ReceiverData *) f->data; +static void receiver_postprocess(MSFilter * f){ + /*ReceiverData *d = (ReceiverData *) f->data;*/ } -static void receiver_uninit(MSFilter * f) -{ +static void receiver_uninit(MSFilter * f){ ReceiverData *d = (ReceiverData *) f->data; - ms_free(f->data); + ms_free(d); } static int receiver_set_session(MSFilter * f, void *arg)