From 9848aa594d9434f66ef7da14004239f874b79a08 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 25 Sep 2010 16:37:23 +0200 Subject: [PATCH] work in progress about dynamic video enablement --- console/commands.c | 72 +++++++++++++++++++++++++++++++++++++++--- console/linphonec.c | 13 ++++++++ console/linphonec.h | 2 ++ coreapi/callbacks.c | 2 ++ coreapi/linphonecall.c | 51 +++++++++++++++++++++++++----- coreapi/linphonecore.h | 7 ++-- coreapi/private.h | 12 ++++--- 7 files changed, 141 insertions(+), 18 deletions(-) diff --git a/console/commands.c b/console/commands.c index 99e2b4ac8..f0148e553 100644 --- a/console/commands.c +++ b/console/commands.c @@ -89,6 +89,7 @@ static int lpc_cmd_resume(LinphoneCore *lc, char *args); static int lpc_cmd_mute_mic(LinphoneCore *lc, char *args); static int lpc_cmd_unmute_mic(LinphoneCore *lc, char *args); static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args); +static int lpc_cmd_camera(LinphoneCore *lc, char *args); static int lpc_cmd_video_window(LinphoneCore *lc, char *args); static int lpc_cmd_states(LinphoneCore *lc, char *args); @@ -136,9 +137,12 @@ static LPC_COMMAND commands[] = { "'help '\t: displays specific help for command.\n" "'help advanced'\t: shows advanced commands.\n" }, - { "call", lpc_cmd_call, "Call a SIP uri", - "'call ' \t: initiate a call to the specified destination.\n" - "'call show' \t: show all the current calls with their id and status.\n" + { "call", lpc_cmd_call, "Call a SIP uri or number", +#ifdef VIDEO_ENABLED + "'call [--audio-only]' \t: initiate a call to the specified destination.\n" +#else + "'call ' \t: initiate a call to the specified destination.\n" +#endif }, { "calls", lpc_cmd_calls, "Show all the current calls with their id and status.", NULL @@ -163,6 +167,11 @@ static LPC_COMMAND commands[] = { "'resume ' : hold off the call with given id\n"}, { "mute", lpc_cmd_mute_mic, "Mute microphone and suspend voice transmission."}, +#ifdef VIDEO_ENABLED + { "camera", lpc_cmd_camera, "Send camera output for current call.", + "'camera on'\t: allow sending of local camera video to remote end.\n" + "'camera off'\t: disable sending of local camera's video to remote end.\n"}, +#endif { "unmute", lpc_cmd_unmute_mic, "Unmute microphone and resume voice transmission."}, { "duration", lpc_cmd_duration, "Print duration in seconds of the last call.", NULL }, @@ -503,12 +512,19 @@ lpc_cmd_call(LinphoneCore *lc, char *args) } { LinphoneCall *call; + LinphoneCallParams *cp=linphone_core_create_default_call_parameters (lc); + char *opt; if ( linphone_core_in_call(lc) ) { linphonec_out("Terminate or hold on the current call first.\n"); return 1; } - if ( NULL == (call=linphone_core_invite(lc, args)) ) + opt=strstr(args,"--audio-only"); + if (opt){ + opt[0]='\0'; + linphone_call_params_enable_video (cp,FALSE); + } + if ( NULL == (call=linphone_core_invite_with_params(lc, args,cp)) ) { linphonec_out("Error from linphone_core_invite.\n"); } @@ -516,6 +532,7 @@ lpc_cmd_call(LinphoneCore *lc, char *args) { snprintf(callee_name,sizeof(callee_name),"%s",args); } + linphone_call_params_destroy(cp); } return 1; } @@ -2261,6 +2278,53 @@ static int lpc_cmd_states(LinphoneCore *lc, char *args){ return 0; } +static int lpc_cmd_camera(LinphoneCore *lc, char *args){ + LinphoneCall *call=linphone_core_get_current_call(lc); + bool_t activated=FALSE; + + if (linphone_core_video_enabled (lc)==FALSE){ + linphonec_out("Video is disabled, re-run linphonec with -V option."); + return 1; + } + + if (args){ + if (strcmp(args,"on")==0) + activated=TRUE; + else if (strcmp(args,"off")==0) + activated=FALSE; + else + return 0; + } + + if (call==NULL){ + if (args){ + linphonec_camera_enabled=activated; + } + if (linphonec_camera_enabled){ + linphonec_out("Camera is enabled. Video stream will be setup immediately for outgoing and incoming calls.\n"); + }else{ + linphonec_out("Camera is disabled. Calls will be established with audio-only, with the possibility to later add video using 'camera on'.\n"); + } + }else{ + const LinphoneCallParams *cp=linphone_call_get_current_params (call); + if (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); + linphonec_out("Trying to bring up video stream..."); + } + } + if (linphone_call_camera_enabled (call)) + linphonec_out("Camera is allowed for current call.\n"); + else linphonec_out("Camera is dis-allowed for current call.\n"); + } + return 1; +} + /*************************************************************************** * * Command table management funx diff --git a/console/linphonec.c b/console/linphonec.c index 6985287d6..4971deaf0 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -173,6 +173,8 @@ static bool_t pipe_reader_run=FALSE; static ortp_pipe_t server_sock; #endif /*_WIN32_WCE*/ +bool_t linphonec_camera_enabled=TRUE; + extern VideoParams lpc_video_params; @@ -313,6 +315,13 @@ linphonec_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, } +static void linphonec_call_updated(LinphoneCall *call){ + const LinphoneCallParams *cp=linphone_call_get_current_params(call); + if (!linphone_call_camera_enabled (call) && linphone_call_params_video_enabled (cp)){ + linphonec_out("Far end requests to share video.\nType 'camera on' if you agree."); + } +} + static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState st, const char *msg){ char *from=linphone_call_get_remote_address_as_string(call); long id=(long)linphone_call_get_user_pointer (call); @@ -337,6 +346,7 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L break; case LinphoneCallIncomingReceived: linphonec_call_identify(call); + linphone_call_enable_camera (call,linphonec_camera_enabled); id=(long)linphone_call_get_user_pointer (call); linphonec_set_caller(from); if ( auto_answer) { @@ -347,6 +357,9 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L case LinphoneCallOutgoingInit: linphonec_call_identify(call); break; + case LinphoneCallUpdatedByRemote: + linphonec_call_updated(call); + break; default: break; } diff --git a/console/linphonec.h b/console/linphonec.h index 4a5844b56..5f91b1b50 100644 --- a/console/linphonec.h +++ b/console/linphonec.h @@ -121,6 +121,8 @@ void linphonec_set_caller(const char *caller); LinphoneCall *linphonec_get_call(long id); void linphonec_call_identify(LinphoneCall* call); +extern bool_t linphonec_camera_enabled; + #endif /* def LINPHONEC_H */ /**************************************************************************** diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 642e3d188..100373f68 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -301,6 +301,8 @@ static void call_updating(SalOp *op){ if (lc->current_call!=call){ ms_error("Inconsitency detected: current call is %p but call %p is being paused !",lc->current_call,call); } + }else{ + linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote"); } /*accept the modification (sends a 200Ok)*/ sal_call_accept(op); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 0d3bfcdbc..03ee842dc 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -145,7 +145,9 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr call->core=lc; linphone_core_get_local_ip(lc,linphone_address_get_domain(to),call->localip); linphone_call_init_common(call,from,to); + call->params=*params; call->localdesc=create_local_media_description (lc,call,params->has_video,FALSE); + call->camera_active=params->has_video; if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun) linphone_core_run_stun_tests(call->core,call); discover_mtu(lc,linphone_address_get_domain (to)); @@ -179,8 +181,10 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro linphone_address_clean(from); linphone_core_get_local_ip(lc,linphone_address_get_domain(from),call->localip); linphone_call_init_common(call, from, to); + call->params.has_video=linphone_core_video_enabled(lc); call->localdesc=create_local_media_description (lc,call, - linphone_core_video_enabled(lc),lc->sip_conf.only_one_codec); + call->params.has_video,lc->sip_conf.only_one_codec); + call->camera_active=call->params.has_video; if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun) linphone_core_run_stun_tests(call->core,call); discover_mtu(lc,linphone_address_get_domain(from)); @@ -260,6 +264,8 @@ const char *linphone_call_state_to_string(LinphoneCallState cs){ return "LinphoneCallEnd"; case LinphoneCallPausedByRemote: return "LinphoneCallPausedByRemote"; + case LinphoneCallUpdatedByRemote: + return "LinphoneCallUpdatedByRemote"; } return "undefined state"; } @@ -337,6 +343,13 @@ void linphone_call_unref(LinphoneCall *obj){ } } +/** + * Returns current parameters associated to the call. +**/ +const LinphoneCallParams * linphone_call_get_current_params(const LinphoneCall *call){ + return &call->params; +} + /** * Returns the remote address associated to this call * @@ -423,6 +436,35 @@ int linphone_call_get_duration(const LinphoneCall *call){ return time(NULL)-call->media_start_time; } +/** + * Indicate whether camera input should be sent to remote end. +**/ +void linphone_call_enable_camera (LinphoneCall *call, bool_t enable){ + call->camera_active=enable; +} + +bool_t linphone_call_camera_enabled (const LinphoneCall *call){ + return call->camera_active; +} + +void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled){ + cp->has_video=enabled; +} + +bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp){ + return cp->has_video; +} + +LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp){ + LinphoneCallParams *ncp=ms_new0(LinphoneCallParams,1); + memcpy(ncp,cp,sizeof(LinphoneCallParams)); + return ncp; +} + +void linphone_call_params_destroy(LinphoneCallParams *p){ + ms_free(p); +} + /** * @} **/ @@ -778,10 +820,3 @@ void linphone_call_stop_media_streams(LinphoneCall *call){ } } -void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled){ - cp->has_video=enabled; -} - -void linphone_call_params_destroy(LinphoneCallParams *p){ - ms_free(p); -} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index b21573b5c..d360f83df 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -163,7 +163,9 @@ char * linphone_call_log_to_str(LinphoneCallLog *cl); struct _LinphoneCallParams; typedef struct _LinphoneCallParams LinphoneCallParams; +LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp); void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled); +bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp); void linphone_call_params_destroy(LinphoneCallParams *cp); /** @@ -200,7 +202,8 @@ typedef enum _LinphoneCallState{ LinphoneCallRefered, LinphoneCallError, LinphoneCallEnd, - LinphoneCallPausedByRemote + LinphoneCallPausedByRemote, + LinphoneCallUpdatedByRemote /**