From 17842d054029b31e53fe5b06524e2c69c3505297 Mon Sep 17 00:00:00 2001 From: Marco Bascetta Date: Wed, 24 Jan 2018 09:24:47 +0100 Subject: [PATCH 16/23] voip/audiostream: changed MSMediaStreamIO parameter analyze. Added single filters check. --- src/voip/audiostream.c | 433 ++++++++++++++++++++++++++++++------------------- 1 file changed, 263 insertions(+), 170 deletions(-) diff --git a/src/voip/audiostream.c b/src/voip/audiostream.c index c6bc93d8..569c85e1 100644 --- a/src/voip/audiostream.c +++ b/src/voip/audiostream.c @@ -819,9 +819,15 @@ int audio_stream_start_from_io(AudioStream *stream, RtpProfile *profile, const c } rtp_session_set_payload_type(rtps,payload); - ms_filter_call_method(stream->ms.rtpsend,MS_RTP_SEND_SET_SESSION,rtps); - stream->ms.rtprecv=ms_factory_create_filter(stream->ms.factory,MS_RTP_RECV_ID); - ms_filter_call_method(stream->ms.rtprecv,MS_RTP_RECV_SET_SESSION,rtps); + if( stream->ms.rtpsend ) { + ms_filter_call_method(stream->ms.rtpsend,MS_RTP_SEND_SET_SESSION,rtps); + } + + //TODO + if( rtps->mode != RTP_SESSION_SENDONLY ) { + stream->ms.rtprecv=ms_factory_create_filter(stream->ms.factory,MS_RTP_RECV_ID); + ms_filter_call_method(stream->ms.rtprecv,MS_RTP_RECV_SET_SESSION,rtps); + } stream->ms.sessions.rtp_session=rtps; if((stream->features & AUDIO_STREAM_FEATURE_DTMF_ECHO) != 0) @@ -837,34 +843,53 @@ int audio_stream_start_from_io(AudioStream *stream, RtpProfile *profile, const c } /* creates the local part */ - if (io->input.type == MSResourceSoundcard){ - if (stream->soundread==NULL) - stream->soundread = ms_snd_card_create_reader(io->input.soundcard); - has_builtin_ec=!!(ms_snd_card_get_capabilities(io->input.soundcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER); - } else if (io->input.type == MSResourceRtp) { - stream->rtp_io_session = io->input.session; - pt = rtp_profile_get_payload(rtp_session_get_profile(stream->rtp_io_session), - rtp_session_get_recv_payload_type(stream->rtp_io_session)); - stream->soundread = ms_factory_create_filter(stream->ms.factory, MS_RTP_RECV_ID); - ms_filter_call_method(stream->soundread, MS_RTP_RECV_SET_SESSION, stream->rtp_io_session); - stream->read_decoder = ms_factory_create_decoder(stream->ms.factory, pt->mime_type); - } else { - stream->soundread=ms_factory_create_filter(stream->ms.factory, MS_FILE_PLAYER_ID); - stream->read_resampler=ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID); - resampler_missing = stream->read_resampler == NULL; - } - if (io->output.type == MSResourceSoundcard) { - if (stream->soundwrite==NULL) - stream->soundwrite=ms_snd_card_create_writer(io->output.soundcard); - } else if (io->output.type == MSResourceRtp) { - stream->rtp_io_session = io->output.session; - pt = rtp_profile_get_payload(rtp_session_get_profile(stream->rtp_io_session), - rtp_session_get_send_payload_type(stream->rtp_io_session)); - stream->soundwrite = ms_factory_create_filter(stream->ms.factory, MS_RTP_SEND_ID); - ms_filter_call_method(stream->soundwrite, MS_RTP_SEND_SET_SESSION, stream->rtp_io_session); - stream->write_encoder = ms_factory_create_encoder(stream->ms.factory,pt->mime_type); - } else { - stream->soundwrite=ms_factory_create_filter(stream->ms.factory, MS_FILE_REC_ID); + switch (io->input.type){ + case MSResourceSoundcard: + if (stream->soundread==NULL) + stream->soundread = ms_snd_card_create_reader(io->input.soundcard); + has_builtin_ec=!!(ms_snd_card_get_capabilities(io->input.soundcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER); + break; + + case MSResourceRtp: + stream->rtp_io_session = io->input.session; + pt = rtp_profile_get_payload(rtp_session_get_profile(stream->rtp_io_session), + rtp_session_get_recv_payload_type(stream->rtp_io_session)); + stream->soundread = ms_factory_create_filter(stream->ms.factory, MS_RTP_RECV_ID); + ms_filter_call_method(stream->soundread, MS_RTP_RECV_SET_SESSION, stream->rtp_io_session); + stream->read_decoder = ms_factory_create_decoder(stream->ms.factory, pt->mime_type); + break; + + case MSResourceFile: + stream->soundread=ms_factory_create_filter(stream->ms.factory, MS_FILE_PLAYER_ID); + stream->read_resampler=ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID); + resampler_missing = stream->read_resampler == NULL; + break; + + default: + break; + } + + switch (io->output.type){ + case MSResourceSoundcard: + if (stream->soundwrite==NULL) + stream->soundwrite=ms_snd_card_create_writer(io->output.soundcard); + break; + + case MSResourceRtp: + stream->rtp_io_session = io->output.session; + pt = rtp_profile_get_payload(rtp_session_get_profile(stream->rtp_io_session), + rtp_session_get_send_payload_type(stream->rtp_io_session)); + stream->soundwrite = ms_factory_create_filter(stream->ms.factory, MS_RTP_SEND_ID); + ms_filter_call_method(stream->soundwrite, MS_RTP_SEND_SET_SESSION, stream->rtp_io_session); + stream->write_encoder = ms_factory_create_encoder(stream->ms.factory,pt->mime_type); + break; + + case MSResourceFile: + stream->soundwrite=ms_factory_create_filter(stream->ms.factory, MS_FILE_REC_ID); + break; + + default: + break; } /* creates the couple of encoder/decoder */ @@ -889,9 +914,13 @@ int audio_stream_start_from_io(AudioStream *stream, RtpProfile *profile, const c if (tev_pt != -1) rtp_session_set_send_telephone_event_payload_type(rtps, tev_pt); - if (ms_filter_call_method(stream->ms.rtpsend,MS_FILTER_GET_SAMPLE_RATE,&sample_rate)!=0){ - ms_error("Sample rate is unknown for RTP side !"); - return -1; + if (stream->ms.rtpsend){ + if (ms_filter_call_method(stream->ms.rtpsend,MS_FILTER_GET_SAMPLE_RATE,&sample_rate)!=0){ + ms_error("Sample rate is unknown for RTP side !"); + return -1; + } + } else { + sample_rate = pt->clock_rate; } if (stream->features == 0) { @@ -899,16 +928,26 @@ int audio_stream_start_from_io(AudioStream *stream, RtpProfile *profile, const c MSPinFormat rtpsend_format = {0}; MSPinFormat rtprecv_format = {0}; MSPinFormat sndwrite_format = {0}; - ms_filter_call_method(stream->ms.rtpsend, MS_FILTER_GET_OUTPUT_FMT, &rtpsend_format); - ms_filter_call_method(stream->soundread, MS_FILTER_GET_OUTPUT_FMT, &sndread_format); - ms_filter_call_method(stream->ms.rtprecv, MS_FILTER_GET_OUTPUT_FMT, &rtprecv_format); - ms_filter_call_method(stream->soundwrite, MS_FILTER_GET_OUTPUT_FMT, &sndwrite_format); + if (stream->ms.rtpsend){ + ms_filter_call_method(stream->ms.rtpsend, MS_FILTER_GET_OUTPUT_FMT, &rtpsend_format); + } + if (stream->soundread){ + ms_filter_call_method(stream->soundread, MS_FILTER_GET_OUTPUT_FMT, &sndread_format); + } + if (stream->ms.rtprecv){ + ms_filter_call_method(stream->ms.rtprecv, MS_FILTER_GET_OUTPUT_FMT, &rtprecv_format); + } + if (stream->soundwrite){ + ms_filter_call_method(stream->soundwrite, MS_FILTER_GET_OUTPUT_FMT, &sndwrite_format); + } if (sndread_format.fmt && rtpsend_format.fmt && rtprecv_format.fmt && sndwrite_format.fmt) { skip_encoder_and_decoder = ms_fmt_descriptor_equals(sndread_format.fmt, rtpsend_format.fmt) && ms_fmt_descriptor_equals(rtprecv_format.fmt, sndwrite_format.fmt); } } do_ts_adjustments = !skip_encoder_and_decoder; - ms_filter_call_method(stream->ms.rtpsend, MS_RTP_SEND_ENABLE_TS_ADJUSTMENT, &do_ts_adjustments); + if (stream->ms.rtpsend){ + ms_filter_call_method(stream->ms.rtpsend, MS_RTP_SEND_ENABLE_TS_ADJUSTMENT, &do_ts_adjustments); + } if (!skip_encoder_and_decoder) { stream->ms.encoder=ms_factory_create_encoder(stream->ms.factory, pt->mime_type); @@ -978,10 +1017,10 @@ int audio_stream_start_from_io(AudioStream *stream, RtpProfile *profile, const c audio_stream_enable_echo_limiter(stream,stream->el_type); audio_stream_enable_noise_gate(stream,stream->use_ng); - if (ms_filter_implements_interface(stream->soundread,MSFilterPlayerInterface) && io->input.file){ + if (stream->soundread && ms_filter_implements_interface(stream->soundread,MSFilterPlayerInterface) && io->input.file){ audio_stream_play(stream,io->input.file); } - if (ms_filter_implements_interface(stream->soundwrite,MSFilterRecorderInterface) && io->output.file){ + if (stream->soundwrite && ms_filter_implements_interface(stream->soundwrite,MSFilterRecorderInterface) && io->output.file){ audio_stream_record(stream,io->output.file); } @@ -1001,22 +1040,26 @@ int audio_stream_start_from_io(AudioStream *stream, RtpProfile *profile, const c ms_filter_call_method(stream->dtmfgen_rtp,MS_FILTER_SET_NCHANNELS,&nchannels); } - /*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*/ - err1 = ms_filter_call_method(stream->soundread, MS_FILTER_SET_SAMPLE_RATE, &sample_rate); - err2 = ms_filter_call_method(stream->soundread, MS_FILTER_SET_NCHANNELS, &nchannels); - /* give the sound filters some properties */ - if (err1 != 0 || err2 != 0){ - /* need to add resampler*/ - if (stream->read_resampler == NULL) stream->read_resampler = ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID); - resampler_missing = stream->read_resampler == NULL; + if (stream->soundread){ + /*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*/ + err1 = ms_filter_call_method(stream->soundread, MS_FILTER_SET_SAMPLE_RATE, &sample_rate); + err2 = ms_filter_call_method(stream->soundread, MS_FILTER_SET_NCHANNELS, &nchannels); + /* give the sound filters some properties */ + if (err1 != 0 || err2 != 0){ + /* need to add resampler*/ + if (stream->read_resampler == NULL) stream->read_resampler = ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID); + resampler_missing = stream->read_resampler == NULL; + } } - err1 = ms_filter_call_method(stream->soundwrite, MS_FILTER_SET_SAMPLE_RATE, &sample_rate); - err2 = ms_filter_call_method(stream->soundwrite, MS_FILTER_SET_NCHANNELS, &nchannels); - if (err1 !=0 || err2 != 0){ - /* need to add resampler*/ - if (stream->write_resampler == NULL) stream->write_resampler = ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID); - resampler_missing = stream->write_resampler == NULL; + if (stream->soundwrite){ + err1 = ms_filter_call_method(stream->soundwrite, MS_FILTER_SET_SAMPLE_RATE, &sample_rate); + err2 = ms_filter_call_method(stream->soundwrite, MS_FILTER_SET_NCHANNELS, &nchannels); + if (err1 !=0 || err2 != 0){ + /* need to add resampler*/ + if (stream->write_resampler == NULL) stream->write_resampler = ms_factory_create_filter(stream->ms.factory, MS_RESAMPLE_ID); + resampler_missing = stream->write_resampler == NULL; + } } if (resampler_missing){ @@ -1214,71 +1257,86 @@ int audio_stream_start_from_io(AudioStream *stream, RtpProfile *profile, const c /* tip: draw yourself the picture if you don't understand */ /*sending graph*/ - ms_connection_helper_start(&h); - ms_connection_helper_link(&h,stream->soundread,-1,0); - if (stream->read_decoder) - ms_connection_helper_link(&h, stream->read_decoder, 0, 0); - if (stream->read_resampler) - ms_connection_helper_link(&h,stream->read_resampler,0,0); - if( stream->mic_equalizer) - ms_connection_helper_link(&h,stream->mic_equalizer, 0, 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); - if (stream->dtmfgen_rtp) - ms_connection_helper_link(&h,stream->dtmfgen_rtp,0,0); - if (stream->outbound_mixer) - ms_connection_helper_link(&h,stream->outbound_mixer,0,0); - if (stream->vaddtx) - ms_connection_helper_link(&h,stream->vaddtx,0,0); - if (!skip_encoder_and_decoder) - ms_connection_helper_link(&h,stream->ms.encoder,0,0); - ms_connection_helper_link(&h,stream->ms.rtpsend,0,-1); + if (stream->soundread && stream->ms.rtpsend) { + ms_connection_helper_start(&h); + ms_connection_helper_link(&h,stream->soundread,-1,0); + if (stream->read_decoder) + ms_connection_helper_link(&h, stream->read_decoder, 0, 0); + if (stream->read_resampler) + ms_connection_helper_link(&h,stream->read_resampler,0,0); + if( stream->mic_equalizer) + ms_connection_helper_link(&h,stream->mic_equalizer, 0, 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); + if (stream->dtmfgen_rtp) + ms_connection_helper_link(&h,stream->dtmfgen_rtp,0,0); + if (stream->outbound_mixer) + ms_connection_helper_link(&h,stream->outbound_mixer,0,0); + if (stream->vaddtx) + ms_connection_helper_link(&h,stream->vaddtx,0,0); + if (!skip_encoder_and_decoder) + ms_connection_helper_link(&h,stream->ms.encoder,0,0); + ms_connection_helper_link(&h,stream->ms.rtpsend,0,-1); + } /*receiving graph*/ - ms_connection_helper_start(&h); - ms_connection_helper_link(&h,stream->ms.rtprecv,-1,0); - if (!skip_encoder_and_decoder) - ms_connection_helper_link(&h,stream->ms.decoder,0,0); - if (stream->plc) - ms_connection_helper_link(&h,stream->plc,0,0); - if (stream->flowcontrol) - ms_connection_helper_link(&h, stream->flowcontrol, 0, 0); - if (stream->dtmfgen) - ms_connection_helper_link(&h,stream->dtmfgen,0,0); - if (stream->volrecv) - ms_connection_helper_link(&h,stream->volrecv,0,0); - if (stream->recv_tee) - ms_connection_helper_link(&h,stream->recv_tee,0,0); - if (stream->spk_equalizer) - ms_connection_helper_link(&h,stream->spk_equalizer,0,0); - if (stream->local_mixer){ - ms_connection_helper_link(&h,stream->local_mixer,0,0); - setup_local_player(stream,sample_rate, nchannels); - } - if (stream->ec) - ms_connection_helper_link(&h,stream->ec,0,0); - if (stream->write_resampler) - ms_connection_helper_link(&h,stream->write_resampler,0,0); - if (stream->write_encoder) - ms_connection_helper_link(&h, stream->write_encoder, 0, 0); - ms_connection_helper_link(&h,stream->soundwrite,0,-1); + if (stream->ms.rtprecv && stream->soundwrite) { + ms_connection_helper_start(&h); + ms_connection_helper_link(&h,stream->ms.rtprecv,-1,0); + if (!skip_encoder_and_decoder) + ms_connection_helper_link(&h,stream->ms.decoder,0,0); + if (stream->plc) + ms_connection_helper_link(&h,stream->plc,0,0); + if (stream->flowcontrol) + ms_connection_helper_link(&h, stream->flowcontrol, 0, 0); + if (stream->dtmfgen) + ms_connection_helper_link(&h,stream->dtmfgen,0,0); + if (stream->volrecv) + ms_connection_helper_link(&h,stream->volrecv,0,0); + if (stream->recv_tee) + ms_connection_helper_link(&h,stream->recv_tee,0,0); + if (stream->spk_equalizer) + ms_connection_helper_link(&h,stream->spk_equalizer,0,0); + if (stream->local_mixer){ + ms_connection_helper_link(&h,stream->local_mixer,0,0); + setup_local_player(stream,sample_rate, nchannels); + } + if (stream->ec) + ms_connection_helper_link(&h,stream->ec,0,0); + if (stream->write_resampler) + ms_connection_helper_link(&h,stream->write_resampler,0,0); + if (stream->write_encoder) + ms_connection_helper_link(&h, stream->write_encoder, 0, 0); + ms_connection_helper_link(&h,stream->soundwrite,0,-1); + } /*call recording part, attached to both outgoing and incoming graphs*/ if (stream->av_recorder.recorder) plumb_av_recorder(stream); - if (stream->recorder){ - ms_filter_link(stream->outbound_mixer,1,stream->recorder_mixer,0); - ms_filter_link(stream->recv_tee,1,stream->recorder_mixer,1); - ms_filter_link(stream->recorder_mixer,0,stream->recorder,0); + + if (stream->recorder_mixer){ + if (stream->outbound_mixer){ + ms_filter_link(stream->outbound_mixer,1,stream->recorder_mixer,0); + } + if (stream->recv_tee){ + ms_filter_link(stream->recv_tee,1,stream->recorder_mixer,1); + } + if (stream->recorder){ + ms_filter_link(stream->recorder_mixer,0,stream->recorder,0); + } } - /*to make sure all preprocess are done before befre processing audio*/ - ms_ticker_attach_multiple(stream->ms.sessions.ticker - ,stream->soundread - ,stream->ms.rtprecv - ,NULL); + audio_stream_mixed_record_start(stream); + + /*to make sure all preprocess are done before before processing audio*/ + if (stream->soundread){ + ms_ticker_attach(stream->ms.sessions.ticker, stream->soundread); + } + if (stream->ms.rtprecv){ + ms_ticker_attach(stream->ms.sessions.ticker, stream->ms.rtprecv); + } stream->ms.start_time=stream->ms.last_packet_time=ms_time(NULL); stream->ms.is_beginning=TRUE; @@ -1297,20 +1355,42 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char 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){ MSMediaStreamIO io = MS_MEDIA_STREAM_IO_INITIALIZER; + int iR; + bool_t prepend_file = FALSE; + ms_warning("[%s:%d] stream->features:0x%0X, remote ip/port: %s/%d, infile:%s, outfile:%s, playcard:%p, captcard:%p, ec:%d\n", __func__, __LINE__, + stream->features, rem_rtp_ip, rem_rtp_port, infile, outfile, playcard, captcard, use_ec + ); - if (playcard){ + if (playcard && outfile) { io.output.type = MSResourceSoundcard; io.output.soundcard = playcard; - }else{ + audio_stream_mixed_record_open(stream, outfile); + }else if (playcard){ + io.output.type = MSResourceSoundcard; + io.output.soundcard = playcard; + }else if (outfile){ io.output.type = MSResourceFile; io.output.file = outfile; + }else{ + io.output.type = MSResourceDefault; +// io.output.type = MSResourceRtp; +// io.output.session = stream->ms.sessions.rtp_session; } - if (captcard){ + + if (captcard && infile) { io.input.type = MSResourceSoundcard; io.input.soundcard = captcard; - }else{ + prepend_file = TRUE; + } else if (captcard){ + io.input.type = MSResourceSoundcard; + io.input.soundcard = captcard; + }else if (infile){ io.input.type = MSResourceFile; io.input.file = infile; + }else{ + io.input.type = MSResourceDefault; +// io.input.type = MSResourceRtp; +// io.input.session = stream->ms.sessions.rtp_session; } if (jitt_comp != -1) rtp_session_set_jitter_compensation(stream->ms.sessions.rtp_session, jitt_comp); @@ -1537,7 +1617,10 @@ AudioStream *audio_stream_new_with_sessions(MSFactory *factory, const MSMediaStr rtp_session_resync(stream->ms.sessions.rtp_session); /*some filters are created right now to allow configuration by the application before start() */ - stream->ms.rtpsend=ms_factory_create_filter(factory, MS_RTP_SEND_ID); + if (sessions->rtp_session->mode != RTP_SESSION_RECVONLY) { + stream->ms.rtpsend=ms_factory_create_filter(factory, MS_RTP_SEND_ID); + } + stream->ms.ice_check_list=NULL; stream->ms.qi=ms_quality_indicator_new(stream->ms.sessions.rtp_session); ms_quality_indicator_set_label(stream->ms.qi,"audio"); @@ -1585,7 +1668,9 @@ int audio_stream_start_now(AudioStream *stream, RtpProfile * prof, const char * } void audio_stream_set_relay_session_id(AudioStream *stream, const char *id){ - ms_filter_call_method(stream->ms.rtpsend, MS_RTP_SEND_SET_RELAY_SESSION_ID,(void*)id); + if (stream->ms.rtpsend){ + ms_filter_call_method(stream->ms.rtpsend, MS_RTP_SEND_SET_RELAY_SESSION_ID,(void*)id); + } } void audio_stream_enable_echo_canceller(AudioStream *st, bool_t enabled){ @@ -1764,8 +1849,12 @@ void audio_stream_stop(AudioStream * stream){ audio_stream_unprepare_sound(stream); }else if (stream->ms.state==MSStreamStarted){ stream->ms.state=MSStreamStopped; - ms_ticker_detach(stream->ms.sessions.ticker,stream->soundread); - ms_ticker_detach(stream->ms.sessions.ticker,stream->ms.rtprecv); + if(stream->soundread){ + ms_ticker_detach(stream->ms.sessions.ticker,stream->soundread); + } + if(stream->ms.rtprecv){ + ms_ticker_detach(stream->ms.sessions.ticker,stream->ms.rtprecv); + } if (stream->ms.ice_check_list != NULL) { ice_check_list_print_route(stream->ms.ice_check_list, "Audio session's route"); @@ -1774,57 +1863,61 @@ void audio_stream_stop(AudioStream * stream){ rtp_stats_display(rtp_session_get_stats(stream->ms.sessions.rtp_session), " AUDIO SESSION'S RTP STATISTICS "); - /*dismantle the outgoing graph*/ - ms_connection_helper_start(&h); - ms_connection_helper_unlink(&h,stream->soundread,-1,0); - if (stream->read_decoder != NULL) - ms_connection_helper_unlink(&h, stream->read_decoder, 0, 0); - if (stream->read_resampler!=NULL) - ms_connection_helper_unlink(&h,stream->read_resampler,0,0); - if( stream->mic_equalizer) - ms_connection_helper_unlink(&h, stream->mic_equalizer, 0,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); - if (stream->dtmfgen_rtp) - ms_connection_helper_unlink(&h,stream->dtmfgen_rtp,0,0); - if (stream->outbound_mixer) - ms_connection_helper_unlink(&h,stream->outbound_mixer,0,0); - if (stream->vaddtx) - ms_connection_helper_unlink(&h,stream->vaddtx,0,0); - if (stream->ms.encoder) - ms_connection_helper_unlink(&h,stream->ms.encoder,0,0); - ms_connection_helper_unlink(&h,stream->ms.rtpsend,0,-1); - - /*dismantle the receiving graph*/ - ms_connection_helper_start(&h); - ms_connection_helper_unlink(&h,stream->ms.rtprecv,-1,0); - if (stream->ms.decoder) - ms_connection_helper_unlink(&h,stream->ms.decoder,0,0); - if (stream->plc!=NULL) - ms_connection_helper_unlink(&h,stream->plc,0,0); - if (stream->flowcontrol != NULL) - ms_connection_helper_unlink(&h, stream->flowcontrol, 0, 0); - if (stream->dtmfgen!=NULL) - ms_connection_helper_unlink(&h,stream->dtmfgen,0,0); - if (stream->volrecv!=NULL) - ms_connection_helper_unlink(&h,stream->volrecv,0,0); - if (stream->recv_tee) - ms_connection_helper_unlink(&h,stream->recv_tee,0,0); - if (stream->spk_equalizer!=NULL) - ms_connection_helper_unlink(&h,stream->spk_equalizer,0,0); - if (stream->local_mixer){ - ms_connection_helper_unlink(&h,stream->local_mixer,0,0); - dismantle_local_player(stream); + if (stream->soundread && stream->ms.rtpsend) { + /*dismantle the outgoing graph*/ + ms_connection_helper_start(&h); + ms_connection_helper_unlink(&h,stream->soundread,-1,0); + if (stream->read_decoder != NULL) + ms_connection_helper_unlink(&h, stream->read_decoder, 0, 0); + if (stream->read_resampler!=NULL) + ms_connection_helper_unlink(&h,stream->read_resampler,0,0); + if( stream->mic_equalizer) + ms_connection_helper_unlink(&h, stream->mic_equalizer, 0,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); + if (stream->dtmfgen_rtp) + ms_connection_helper_unlink(&h,stream->dtmfgen_rtp,0,0); + if (stream->outbound_mixer) + ms_connection_helper_unlink(&h,stream->outbound_mixer,0,0); + if (stream->vaddtx) + ms_connection_helper_unlink(&h,stream->vaddtx,0,0); + if (stream->ms.encoder) + ms_connection_helper_unlink(&h,stream->ms.encoder,0,0); + ms_connection_helper_unlink(&h,stream->ms.rtpsend,0,-1); + } + + if (stream->ms.rtprecv && stream->soundwrite) { + /*dismantle the receiving graph*/ + ms_connection_helper_start(&h); + ms_connection_helper_unlink(&h,stream->ms.rtprecv,-1,0); + if (stream->ms.decoder) + ms_connection_helper_unlink(&h,stream->ms.decoder,0,0); + if (stream->plc!=NULL) + ms_connection_helper_unlink(&h,stream->plc,0,0); + if (stream->flowcontrol != NULL) + ms_connection_helper_unlink(&h, stream->flowcontrol, 0, 0); + if (stream->dtmfgen!=NULL) + ms_connection_helper_unlink(&h,stream->dtmfgen,0,0); + if (stream->volrecv!=NULL) + ms_connection_helper_unlink(&h,stream->volrecv,0,0); + if (stream->recv_tee) + ms_connection_helper_unlink(&h,stream->recv_tee,0,0); + if (stream->spk_equalizer!=NULL) + ms_connection_helper_unlink(&h,stream->spk_equalizer,0,0); + if (stream->local_mixer){ + ms_connection_helper_unlink(&h,stream->local_mixer,0,0); + dismantle_local_player(stream); + } + if (stream->ec!=NULL) + ms_connection_helper_unlink(&h,stream->ec,0,0); + if (stream->write_resampler!=NULL) + ms_connection_helper_unlink(&h,stream->write_resampler,0,0); + if (stream->write_encoder != NULL) + ms_connection_helper_unlink(&h, stream->write_encoder, 0, 0); + ms_connection_helper_unlink(&h,stream->soundwrite,0,-1); } - if (stream->ec!=NULL) - ms_connection_helper_unlink(&h,stream->ec,0,0); - if (stream->write_resampler!=NULL) - ms_connection_helper_unlink(&h,stream->write_resampler,0,0); - if (stream->write_encoder != NULL) - ms_connection_helper_unlink(&h, stream->write_encoder, 0, 0); - ms_connection_helper_unlink(&h,stream->soundwrite,0,-1); /*dismantle the call recording */ if (stream->av_recorder.recorder) -- 2.11.0