From: Ghislain MARY Date: Wed, 1 Aug 2012 13:16:47 +0000 (+0200) Subject: Defer call update when adding video during communication if ICE is activated to wait... X-Git-Url: http://sjero.net/git/?p=linphone;a=commitdiff_plain;h=652471f66f15c87f8625fdf82c270d38ae5d7038 Defer call update when adding video during communication if ICE is activated to wait for ICE candidates gathering to finish. --- diff --git a/console/commands.c b/console/commands.c index 47253179..7bebdd82 100644 --- a/console/commands.c +++ b/console/commands.c @@ -2503,10 +2503,7 @@ static int lpc_cmd_camera(LinphoneCore *lc, char *args){ linphone_call_enable_camera(call,activated); if ((activated && !linphone_call_params_video_enabled (cp))){ /*update the call to add the video stream*/ - LinphoneCallParams *ncp=linphone_call_params_copy(cp); - linphone_call_params_enable_video(ncp,TRUE); - linphone_core_update_call(lc,call,ncp); - linphone_call_params_destroy (ncp); + linphone_call_enable_video(call,TRUE); linphonec_out("Trying to bring up video stream...\n"); } } diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index edf381a9..c8b4c82d 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -548,6 +548,26 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const } } +void linphone_call_enable_video(LinphoneCall *call, bool_t enabled) +{ + LinphoneCore *lc=linphone_call_get_core(call); + LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call)); + + linphone_call_params_enable_video(params, enabled); + if ((enabled == TRUE) && (sal_op_get_ice_session(call->op))) { + /* Defer call update until the ICE candidates gathering process has finished. */ + ms_message("Defer call update to gather ICE candidates"); + call->params = *params; + update_local_media_description(lc, call); + linphone_call_init_video_stream(call); + video_stream_start_ice_gathering(call->videostream); + linphone_core_gather_ice_candidates(lc, call); + } else { + linphone_core_update_call(lc, call, params); + } + linphone_call_params_destroy(params); +} + static void linphone_call_destroy(LinphoneCall *obj) { if (obj->op!=NULL) { @@ -930,7 +950,7 @@ void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, Lin #endif } -void linphone_call_init_media_streams(LinphoneCall *call){ +void linphone_call_init_audio_stream(LinphoneCall *call){ LinphoneCore *lc=call->core; SalMediaDescription *md=call->localdesc; AudioStream *audiostream; @@ -975,15 +995,20 @@ void linphone_call_init_media_streams(LinphoneCall *call){ call->audiostream_app_evq = ortp_ev_queue_new(); rtp_session_register_event_queue(audiostream->session,call->audiostream_app_evq); +} +void linphone_call_init_video_stream(LinphoneCall *call){ #ifdef VIDEO_ENABLED + LinphoneCore *lc=call->core; + SalMediaDescription *md=call->localdesc; + IceSession *ice_session = sal_op_get_ice_session(call->op); if ((lc->video_conf.display || lc->video_conf.capture) && md->streams[1].rtp_port>0){ int video_recv_buf_size=lp_config_get_int(lc->config,"video","recv_buf_size",0); call->videostream=video_stream_new(md->streams[1].rtp_port,md->streams[1].rtcp_port,linphone_core_ipv6_enabled(lc)); video_stream_enable_display_filter_auto_rotate(call->videostream, lp_config_get_int(lc->config,"video","display_filter_auto_rotate",0)); if (video_recv_buf_size>0) rtp_session_set_recv_buf_size(call->videostream->session,video_recv_buf_size); - + if( lc->video_conf.displaytype != NULL) video_stream_set_display_filter_name(call->videostream,lc->video_conf.displaytype); video_stream_set_event_callback(call->videostream,video_stream_event_cb, call); @@ -1008,6 +1033,11 @@ void linphone_call_init_media_streams(LinphoneCall *call){ #endif } +void linphone_call_init_media_streams(LinphoneCall *call){ + linphone_call_init_audio_stream(call); + linphone_call_init_video_stream(call); +} + static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'}; @@ -1687,6 +1717,49 @@ static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){ linphone_core_terminate_call(lc,call); } +static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ + OrtpEventType evt=ortp_event_get_type(ev); + OrtpEventData *evd=ortp_event_get_data(ev); + + if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) { + if (ice_session_role(sal_op_get_ice_session(call->op)) == IR_Controlling) { + linphone_core_update_call(call->core, call, &call->current_params); + } + } else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) { + IceSession *ice_session = sal_op_get_ice_session(call->op); + LinphoneCallParams *params; + switch (call->state) { + case LinphoneCallStreamsRunning: + if (evd->info.ice_processing_successful==TRUE) { + ice_session_compute_candidates_foundations(ice_session); + ice_session_eliminate_redundant_candidates(ice_session); + ice_session_choose_default_candidates(ice_session); + } + params = linphone_call_params_copy(linphone_call_get_current_params(call)); + linphone_call_params_enable_video(params, TRUE); + linphone_core_update_call(call->core, call, params); + linphone_call_params_destroy(params); + break; + case LinphoneCallOutgoingInit: + default: + linphone_call_stop_media_streams(call); + if (evd->info.ice_processing_successful==TRUE) { + ice_session_compute_candidates_foundations(ice_session); + ice_session_eliminate_redundant_candidates(ice_session); + ice_session_choose_default_candidates(ice_session); + } else { + linphone_call_delete_ice_session(call); + } + if (call->state==LinphoneCallOutgoingInit) { + linphone_core_start_invite(call->core,call,NULL); + } else { + linphone_core_notify_incoming_call(call->core,call); + } + break; + } + } +} + void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapsed){ LinphoneCore* lc = call->core; int disconnect_timeout = linphone_core_get_nortp_timeout(call->core); @@ -1740,25 +1813,8 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse evd->packet = NULL; if (lc->vtable.call_stats_updated) lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]); - } else if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) { - if (ice_session_role(sal_op_get_ice_session(call->op)) == IR_Controlling) { - linphone_core_update_call(lc, call, &call->current_params); - } - } else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) { - IceSession *ice_session = sal_op_get_ice_session(call->op); - linphone_call_stop_media_streams(call); - if (evd->info.ice_processing_successful==TRUE) { - ice_session_compute_candidates_foundations(ice_session); - ice_session_eliminate_redundant_candidates(ice_session); - ice_session_choose_default_candidates(ice_session); - } else { - linphone_call_delete_ice_session(call); - } - if (call->state==LinphoneCallOutgoingInit) { - linphone_core_start_invite(call->core,call,NULL); - } else { - linphone_core_notify_incoming_call(call->core,call); - } + } else if ((evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) || (evt == ORTP_EVENT_ICE_GATHERING_FINISHED)) { + handle_ice_events(call, ev); } ortp_event_destroy(ev); } @@ -1797,25 +1853,8 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse evd->packet = NULL; if (lc->vtable.call_stats_updated) lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]); - } else if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) { - if (ice_session_role(sal_op_get_ice_session(call->op)) == IR_Controlling) { - linphone_core_update_call(lc, call, &call->current_params); - } - } else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) { - IceSession *ice_session = sal_op_get_ice_session(call->op); - linphone_call_stop_media_streams(call); - if (evd->info.ice_processing_successful==TRUE) { - ice_session_compute_candidates_foundations(ice_session); - ice_session_eliminate_redundant_candidates(ice_session); - ice_session_choose_default_candidates(ice_session); - } else { - linphone_call_delete_ice_session(call); - } - if (call->state==LinphoneCallOutgoingInit) { - linphone_core_start_invite(call->core,call,NULL); - } else { - linphone_core_notify_incoming_call(call->core,call); - } + } else if ((evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) || (evt == ORTP_EVENT_ICE_GATHERING_FINISHED)) { + handle_ice_events(call, ev); } ortp_event_destroy(ev); } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 67e887c6..6b00cbc0 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -390,6 +390,15 @@ void linphone_call_enable_echo_limiter(LinphoneCall *call, bool_t val); **/ bool_t linphone_call_echo_limiter_enabled(const LinphoneCall *call); +/** + * Enable or disable video for this call. + * @param call + * @param enabled + * + * @ingroup media_parameters + */ +void linphone_call_enable_video(LinphoneCall *call, bool_t enabled); + /*keep this in sync with mediastreamer2/msvolume.h*/ /** diff --git a/coreapi/private.h b/coreapi/private.h index 1b826c57..61d1d417 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -243,6 +243,8 @@ void linphone_core_play_tone(LinphoneCore *lc); void linphone_call_init_stats(LinphoneCallStats *stats, int type); +void linphone_call_init_audio_stream(LinphoneCall *call); +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); diff --git a/gtk/incall_view.c b/gtk/incall_view.c index 7e8eb683..45e98609 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -221,12 +221,8 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){ static void video_button_clicked(GtkWidget *button, LinphoneCall *call){ gboolean adding=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),"adding_video")); - LinphoneCore *lc=linphone_call_get_core(call); - LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call)); gtk_widget_set_sensitive(button,FALSE); - linphone_call_params_enable_video(params,adding); - linphone_core_update_call(lc,call,params); - linphone_call_params_destroy(params); + linphone_call_enable_video(call,adding); } void linphone_gtk_update_video_button(LinphoneCall *call){