From 85ad456a10df3a23d9004e316ff928c3965ae4e7 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 26 Sep 2012 15:29:47 +0200 Subject: [PATCH] Prevent deleting streams (and therefore RTP sessions) when switching form ICE gathering to the call. This prevents losing the first ICE connectivity checks if the restart of the streams is slow. --- coreapi/linphonecall.c | 35 +++++++++++++++++++++++++++++------ coreapi/linphonecore.c | 20 +++++++++++--------- coreapi/misc.c | 11 +++++++++++ coreapi/private.h | 4 ++++ 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index d43c457b6..8c109c3d9 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -413,6 +413,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro linphone_call_init_common(call, from, to); linphone_core_init_default_params(lc, &call->params); call->params.has_video &= !!lc->video_policy.automatically_accept; + call->params.has_video &= linphone_core_media_description_contains_video_stream(sal_call_get_remote_media_description(op)); switch (linphone_core_get_firewall_policy(call->core)) { case LinphonePolicyUseIce: call->ice_session = ice_session_new(); @@ -424,7 +425,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro if (linphone_core_gather_ice_candidates(call->core,call)<0) { /* Ice candidates gathering failed, proceed with the call anyway. */ linphone_call_delete_ice_session(call); - linphone_call_stop_media_streams(call); + linphone_call_stop_media_streams_for_ice_gathering(call); } } break; @@ -965,9 +966,11 @@ void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, Lin void linphone_call_init_audio_stream(LinphoneCall *call){ LinphoneCore *lc=call->core; AudioStream *audiostream; - int dscp=linphone_core_get_audio_dscp(lc); + int dscp; + if (call->audiostream != NULL) return; call->audiostream=audiostream=audio_stream_new(call->audio_port,call->audio_port+1,linphone_core_ipv6_enabled(lc)); + dscp=linphone_core_get_audio_dscp(lc); if (dscp!=-1) audio_stream_set_dscp(audiostream,dscp); if (linphone_core_echo_limiter_enabled(lc)){ @@ -1020,6 +1023,11 @@ void linphone_call_init_video_stream(LinphoneCall *call){ #ifdef VIDEO_ENABLED LinphoneCore *lc=call->core; + if (!call->params.has_video) { + linphone_call_stop_video_stream(call); + return; + } + if (call->videostream != NULL) return; if ((lc->video_conf.display || lc->video_conf.capture) && call->params.has_video){ int video_recv_buf_size=lp_config_get_int(lc->config,"video","recv_buf_size",0); int dscp=linphone_core_get_video_dscp(lc); @@ -1535,6 +1543,15 @@ void linphone_call_start_media_streams_for_ice_gathering(LinphoneCall *call){ #endif } +void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call){ + audio_stream_unprepare_sound(call->audiostream); +#ifdef VIDEO_ENABLED + if (call->videostream) { + video_stream_unprepare_video(call->videostream); + } +#endif +} + void linphone_call_delete_ice_session(LinphoneCall *call){ if (call->ice_session != NULL) { ice_session_destroy(call->ice_session); @@ -1551,7 +1568,7 @@ static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){ log->quality=audio_stream_get_average_quality_rating(st); } -void linphone_call_stop_media_streams(LinphoneCall *call){ +void linphone_call_stop_audio_stream(LinphoneCall *call) { if (call->audiostream!=NULL) { call->audiostream->ice_check_list = NULL; rtp_session_unregister_event_queue(call->audiostream->session,call->audiostream_app_evq); @@ -1574,8 +1591,9 @@ void linphone_call_stop_media_streams(LinphoneCall *call){ audio_stream_stop(call->audiostream); call->audiostream=NULL; } +} - +void linphone_call_stop_video_stream(LinphoneCall *call) { #ifdef VIDEO_ENABLED if (call->videostream!=NULL){ call->videostream->ice_check_list = NULL; @@ -1587,6 +1605,11 @@ void linphone_call_stop_media_streams(LinphoneCall *call){ call->videostream=NULL; } #endif +} + +void linphone_call_stop_media_streams(LinphoneCall *call){ + linphone_call_stop_audio_stream(call); + linphone_call_stop_video_stream(call); ms_event_queue_skip(call->core->msevq); if (call->audio_profile){ @@ -1812,11 +1835,11 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ linphone_core_start_accept_call_update(call->core, call); break; case LinphoneCallOutgoingInit: - linphone_call_stop_media_streams(call); + linphone_call_stop_media_streams_for_ice_gathering(call); linphone_core_proceed_with_invite_if_ready(call->core, call, NULL); break; default: - linphone_call_stop_media_streams(call); + linphone_call_stop_media_streams_for_ice_gathering(call); linphone_core_notify_incoming_call(call->core, call); break; } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 1a7b97de0..b55c08ece 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1916,7 +1916,7 @@ void linphone_core_iterate(LinphoneCore *lc){ ms_warning("ICE candidates gathering from [%s] has not finished yet, proceed with the call without ICE anyway." ,linphone_core_get_stun_server(lc)); linphone_call_delete_ice_session(call); - linphone_call_stop_media_streams(call); + linphone_call_stop_media_streams_for_ice_gathering(call); } linphone_core_start_invite(lc,call); } @@ -2379,7 +2379,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const if (linphone_core_gather_ice_candidates(lc,call)<0) { /* Ice candidates gathering failed, proceed with the call anyway. */ linphone_call_delete_ice_session(call); - linphone_call_stop_media_streams(call); + linphone_call_stop_media_streams_for_ice_gathering(call); } else { use_ice = TRUE; } @@ -2678,6 +2678,7 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const ms_warning("Video isn't supported in conference"); call->params.has_video = FALSE; } + call->params.has_video &= linphone_core_media_description_contains_video_stream(sal_call_get_remote_media_description(call->op)); call->camera_active=call->params.has_video; update_local_media_description(lc,call); if (call->ice_session != NULL) { @@ -2791,19 +2792,20 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, if (contact) sal_op_set_contact(call->op,contact); + if (params){ + call->params=*params; + call->params.has_video &= linphone_core_media_description_contains_video_stream(sal_call_get_remote_media_description(call->op)); + call->camera_active=call->params.has_video; + update_local_media_description(lc,call); + sal_call_set_local_media_description(call->op,call->localdesc); + } + if (call->audiostream==NULL) linphone_call_init_media_streams(call); if (!was_ringing && call->audiostream->ticker==NULL){ audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard); } - if (params){ - call->params=*params; - call->camera_active=call->params.has_video; - update_local_media_description(lc,call); - sal_call_set_local_media_description(call->op,call->localdesc); - } - sal_call_accept(call->op); if (lc->vtable.display_status!=NULL) lc->vtable.display_status(lc,_("Connected.")); diff --git a/coreapi/misc.c b/coreapi/misc.c index be977400f..5cb2a49f2 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -904,6 +904,17 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, } } +bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md) +{ + int i; + + for (i = 0; i < md->nstreams; i++) { + if ((md->streams[i].type == SalVideo) && (md->streams[i].rtp_port != 0)) + return TRUE; + } + return FALSE; +} + void linphone_core_deactivate_ice_for_deactivated_media_streams(LinphoneCall *call, const SalMediaDescription *md) { int i; diff --git a/coreapi/private.h b/coreapi/private.h index d8e07c1b9..ea21a967a 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -251,6 +251,7 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call); void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call); void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session); void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md); +bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md); void linphone_core_deactivate_ice_for_deactivated_media_streams(LinphoneCall *call, const SalMediaDescription *md); void linphone_core_send_initial_subscribes(LinphoneCore *lc); @@ -280,8 +281,11 @@ void linphone_call_init_video_stream(LinphoneCall *call); void linphone_call_init_media_streams(LinphoneCall *call); void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone); void linphone_call_start_media_streams_for_ice_gathering(LinphoneCall *call); +void linphone_call_stop_audio_stream(LinphoneCall *call); +void linphone_call_stop_video_stream(LinphoneCall *call); void linphone_call_stop_media_streams(LinphoneCall *call); void linphone_call_delete_ice_session(LinphoneCall *call); +void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call); const char * linphone_core_get_identity(LinphoneCore *lc); const char * linphone_core_get_route(LinphoneCore *lc);