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);