Defer call update when adding video during communication if ICE is activated to wait for ICE candidates gathering to finish.

This commit is contained in:
Ghislain MARY 2012-08-01 15:16:47 +02:00
parent 981accf8bb
commit 652471f66f
5 changed files with 92 additions and 49 deletions

View file

@ -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");
}
}

View file

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

View file

@ -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*/
/**

View file

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

View file

@ -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){