]> sjero.net Git - linphone/commitdiff
wip - conferencing
authorSimon Morlat <simon.morlat@linphone.org>
Mon, 12 Sep 2011 20:42:53 +0000 (22:42 +0200)
committerSimon Morlat <simon.morlat@linphone.org>
Mon, 12 Sep 2011 20:42:53 +0000 (22:42 +0200)
coreapi/Makefile.am
coreapi/conference.c [new file with mode: 0644]
coreapi/linphonecall.c
coreapi/linphonecore.c
coreapi/linphonecore.h
coreapi/private.h
mediastreamer2

index 6ea151e0ab4ca032443cc3c0ee8310cc1f9be1e7..e9cfe715b70a83da0fbcc8ad972ff28934066d24 100644 (file)
@@ -36,7 +36,8 @@ liblinphone_la_SOURCES=\
        sipsetup.c sipsetup.h \
        siplogin.c \
        lsd.c linphonecore_utils.h \
-       ec-calibrator.c
+       ec-calibrator.c \
+       conference.c
 
 
 liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined
diff --git a/coreapi/conference.c b/coreapi/conference.c
new file mode 100644 (file)
index 0000000..e97f258
--- /dev/null
@@ -0,0 +1,108 @@
+/***************************************************************************
+ *            conference.c
+ *
+ *  Mon Sep 12, 2011
+ *  Copyright  2011  Belledonne Communications
+ *  Author: Simon Morlat
+ *  Email simon dot morlat at linphone dot org
+ ****************************************************************************/
+
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include "private.h"
+
+
+static void conference_check_init(LinphoneConference *ctx){
+       if (ctx->conf==NULL){
+               ctx->conf=ms_audio_conference_new();
+       }
+}
+
+static void conference_check_uninit(LinphoneConference *ctx){
+       if (ctx->conf){
+               if (ctx->conf->nmembers==0){
+                       ms_audio_conference_destroy(ctx->conf);
+                       ctx->conf=NULL;
+               }
+       }
+}
+
+
+void linphone_call_add_to_conf(LinphoneCall *call){
+       LinphoneCore *lc=call->core;
+       LinphoneConference *conf=&lc->conf_ctx;
+       MSAudioEndpoint *ep;
+       ep=ms_audio_endpoint_get_from_stream(call->audiostream,TRUE);
+       ms_audio_conference_add_member(conf->conf,ep);
+       call->endpoint=ep;
+}
+
+void linphone_call_remove_from_conf(LinphoneCall *call){
+       LinphoneCore *lc=call->core;
+       LinphoneConference *conf=&lc->conf_ctx;
+       
+       ms_audio_conference_remove_member(conf->conf,call->endpoint);
+       ms_audio_endpoint_release_from_stream(call->endpoint);
+       call->endpoint=NULL;
+       conference_check_uninit(conf);
+}
+
+int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call){
+       LinphoneCallParams params;
+       if (call->current_params.in_conference){
+               ms_error("Already in conference");
+               return -1;
+       }
+       conference_check_init(&lc->conf_ctx);
+       call->params.in_conference=TRUE;
+       call->params.has_video=FALSE;
+       params=call->params;
+       if (call->state==LinphoneCallPaused)
+               linphone_core_resume_call(lc,call);
+       else if (call->state==LinphoneCallStreamsRunning){
+               /*this will trigger a reINVITE that will later redraw the streams */
+               linphone_core_update_call(lc,call,&params);
+       }else{
+               ms_error("Call is in state %s, it cannot be added to the conference.",linphone_call_state_to_string(call->state));
+               return -1;
+       }
+       return 0;
+}
+
+int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call){
+       if (!call->current_params.in_conference){
+               if (call->params.in_conference){
+                       ms_warning("Not (yet) in conference, be patient");
+                       return -1;
+               }else{
+                       ms_error("Not in a conference.");
+                       return -1;
+               }
+       }
+       call->params.in_conference=FALSE;
+       return linphone_core_pause_call(lc,call);
+}
+
+int linphone_core_pause_conference(LinphoneCore *lc){
+       return 0;
+}
+
+
+int linphone_core_resume_conference(LinphoneCore *lc){
+       return 0;
+}
+
index 210c2c453817448341c2bb3fb9b58f31688fea59..80f681f4495bcf3fb6e8eaa307818e32ce1c3769 100644 (file)
@@ -834,10 +834,7 @@ static void parametrize_equalizer(LinphoneCore *lc, AudioStream *st){
        }
 }
 
-
-static void post_configure_audio_streams(LinphoneCall*call){
-       AudioStream *st=call->audiostream;
-       LinphoneCore *lc=call->core;
+static void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t muted){
        float mic_gain=lp_config_get_float(lc->config,"sound","mic_gain",1);
        float thres = 0;
        float recv_gain;
@@ -845,7 +842,7 @@ static void post_configure_audio_streams(LinphoneCall*call){
        float ng_floorgain=lp_config_get_float(lc->config,"sound","ng_floorgain",0);
        int dc_removal=lp_config_get_int(lc->config,"sound","dc_removal",0);
        
-       if (!call->audio_muted)
+       if (!muted)
                audio_stream_set_mic_gain(st,mic_gain);
        else 
                audio_stream_set_mic_gain(st,0);
@@ -884,6 +881,12 @@ static void post_configure_audio_streams(LinphoneCall*call){
                ms_filter_call_method(st->volrecv,MS_VOLUME_SET_NOISE_GATE_FLOORGAIN,&floorgain);
        }
        parametrize_equalizer(lc,st);
+}
+
+static void post_configure_audio_streams(LinphoneCall*call){
+       AudioStream *st=call->audiostream;
+       LinphoneCore *lc=call->core;
+       _post_configure_audio_stream(st,lc,call->audio_muted);
        if (lc->vtable.dtmf_received!=NULL){
                /* replace by our default action*/
                audio_stream_play_received_dtmfs(call->audiostream,FALSE);
@@ -953,18 +956,167 @@ static void setup_ring_player(LinphoneCore *lc, LinphoneCall *call){
        ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time);
 }
 
+#define LINPHONE_RTCP_SDES_TOOL "Linphone-" LINPHONE_VERSION
+
+static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cname, bool_t muted, bool_t send_ringbacktone, bool_t use_arc){
+       LinphoneCore *lc=call->core;
+       int jitt_comp=lc->rtp_conf.audio_jitt_comp;
+       int used_pt=-1;
+       const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
+                                               SalProtoRtpAvp,SalAudio);
+       
+       if (stream && stream->dir!=SalStreamInactive && stream->port!=0){
+               MSSndCard *playcard=lc->sound_conf.lsd_card ? 
+                       lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
+               MSSndCard *captcard=lc->sound_conf.capt_sndcard;
+               const char *playfile=lc->play_file;
+               const char *recfile=lc->rec_file;
+               call->audio_profile=make_profile(call,call->resultdesc,stream,&used_pt);
+               bool_t use_ec;
+
+               if (used_pt!=-1){
+                       if (playcard==NULL) {
+                               ms_warning("No card defined for playback !");
+                       }
+                       if (captcard==NULL) {
+                               ms_warning("No card defined for capture !");
+                       }
+                       /*Replace soundcard filters by inactive file players or recorders
+                        when placed in recvonly or sendonly mode*/
+                       if (stream->port==0 || stream->dir==SalStreamRecvOnly){
+                               captcard=NULL;
+                               playfile=NULL;
+                       }else if (stream->dir==SalStreamSendOnly){
+                               playcard=NULL;
+                               captcard=NULL;
+                               recfile=NULL;
+                               /*And we will eventually play "playfile" if set by the user*/
+                               /*playfile=NULL;*/
+                       }
+                       if (send_ringbacktone){
+                               captcard=NULL;
+                               playfile=NULL;/* it is setup later*/
+                       }
+                       /*if playfile are supplied don't use soundcards*/
+                       if (lc->use_files) {
+                               captcard=NULL;
+                               playcard=NULL;
+                       }
+                       if (call->params.in_conference){
+                               /* first create the graph without soundcard resources*/
+                               captcard=playcard=NULL;
+                       }
+                       use_ec=captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc);
+
+                       audio_stream_enable_adaptive_bitrate_control(call->audiostream,use_arc);
+                       audio_stream_start_full(
+                               call->audiostream,
+                               call->audio_profile,
+                               stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr,
+                               stream->port,
+                               stream->port+1,
+                               used_pt,
+                               jitt_comp,
+                               playfile,
+                               recfile,
+                               playcard,
+                               captcard,
+                               use_ec
+                               );
+                       post_configure_audio_streams(call);
+                       if (muted && !send_ringbacktone){
+                               audio_stream_set_mic_gain(call->audiostream,0);
+                       }
+                       if (stream->dir==SalStreamSendOnly && playfile!=NULL){
+                               int pause_time=500;
+                               ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time);
+                       }
+                       if (send_ringbacktone){
+                               setup_ring_player(lc,call);
+                       }
+                       audio_stream_set_rtcp_information(call->audiostream, cname, LINPHONE_RTCP_SDES_TOOL);
+                       if (call->params.in_conference){
+                               /*transform the graph to connect it to the conference filter */
+                               linphone_call_add_to_conf(call);
+                       }
+               }else ms_warning("No audio stream accepted ?");
+       }       
+}
+
+static void linphone_call_start_video_stream(LinphoneCall *call, const char *cname,bool_t all_inputs_muted){
+#ifdef VIDEO_ENABLED
+       LinphoneCore *lc=call->core;
+       int used_pt=-1;
+       const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc,
+                                                       SalProtoRtpAvp,SalVideo);
+       /* shutdown preview */
+       if (lc->previewstream!=NULL) {
+               video_preview_stop(lc->previewstream);
+               lc->previewstream=NULL;
+       }
+       call->current_params.has_video=FALSE;
+       if (vstream && vstream->dir!=SalStreamInactive && vstream->port!=0) {
+               const char *addr=vstream->addr[0]!='\0' ? vstream->addr : call->resultdesc->addr;
+               call->video_profile=make_profile(call,call->resultdesc,vstream,&used_pt);
+               if (used_pt!=-1){
+                       VideoStreamDir dir=VideoStreamSendRecv;
+                       MSWebCam *cam=lc->video_conf.device;
+                       bool_t is_inactive=FALSE;
+
+                       call->current_params.has_video=TRUE;
+                       
+                       video_stream_set_sent_video_size(call->videostream,linphone_core_get_preferred_video_size(lc));
+                       video_stream_enable_self_view(call->videostream,lc->video_conf.selfview);
+                       if (lc->video_window_id!=0)
+                               video_stream_set_native_window_id(call->videostream,lc->video_window_id);
+                       if (lc->preview_window_id!=0)
+                               video_stream_set_native_preview_window_id (call->videostream,lc->preview_window_id);
+                       video_stream_use_preview_video_window (call->videostream,lc->use_preview_window);
+                       
+                       if (vstream->dir==SalStreamSendOnly && lc->video_conf.capture ){
+                               cam=get_nowebcam_device();
+                               dir=VideoStreamSendOnly;
+                       }else if (vstream->dir==SalStreamRecvOnly && lc->video_conf.display ){
+                               dir=VideoStreamRecvOnly;
+                       }else if (vstream->dir==SalStreamSendRecv){
+                               if (lc->video_conf.display && lc->video_conf.capture)
+                                       dir=VideoStreamSendRecv;
+                               else if (lc->video_conf.display)
+                                       dir=VideoStreamRecvOnly;
+                               else
+                                       dir=VideoStreamSendOnly;
+                       }else{
+                               ms_warning("video stream is inactive.");
+                               /*either inactive or incompatible with local capabilities*/
+                               is_inactive=TRUE;
+                       }
+                       if (call->camera_active==FALSE || all_inputs_muted){
+                               cam=get_nowebcam_device();
+                       }
+                       if (!is_inactive){
+                               video_stream_set_direction (call->videostream, dir);
+                               video_stream_start(call->videostream,
+                                       call->video_profile, addr, vstream->port,
+                                       vstream->port+1,
+                                       used_pt, lc->rtp_conf.audio_jitt_comp, cam);
+                               video_stream_set_rtcp_information(call->videostream, cname,LINPHONE_RTCP_SDES_TOOL);
+                       }
+               }else ms_warning("No video stream accepted.");
+       }else{
+               ms_warning("No valid video stream defined.");
+       }
+#endif
+}
 
 void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone){
        LinphoneCore *lc=call->core;
        LinphoneAddress *me=linphone_core_get_primary_contact_parsed(lc);
-       const char *tool="linphone-" LINPHONE_VERSION;
        char *cname;
-       int used_pt=-1;
+       bool_t use_arc;
 #ifdef VIDEO_ENABLED
        const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc,
                                                        SalProtoRtpAvp,SalVideo);
 #endif
-       bool_t use_arc=linphone_core_adaptive_rate_control_enabled(lc);
        
        if(call->audiostream == NULL)
        {
@@ -972,155 +1124,18 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
                return;
        }
        call->current_params = call->params;
-       /* adjust rtp jitter compensation. It must be at least the latency of the sound card */
-       int jitt_comp=MAX(lc->sound_conf.latency,lc->rtp_conf.audio_jitt_comp);
-
        if (call->media_start_time==0) call->media_start_time=time(NULL);
-
        cname=linphone_address_as_string_uri_only(me);
-       {
-               const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
-                                                       SalProtoRtpAvp,SalAudio);
-               if (stream && stream->dir!=SalStreamInactive && stream->port!=0){
-                       MSSndCard *playcard=lc->sound_conf.lsd_card ? 
-                               lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
-                       MSSndCard *captcard=lc->sound_conf.capt_sndcard;
-                       const char *playfile=lc->play_file;
-                       const char *recfile=lc->rec_file;
-                       call->audio_profile=make_profile(call,call->resultdesc,stream,&used_pt);
-                       bool_t use_ec,use_arc_audio=use_arc;
-
-                       if (used_pt!=-1){
-                               if (playcard==NULL) {
-                                       ms_warning("No card defined for playback !");
-                               }
-                               if (captcard==NULL) {
-                                       ms_warning("No card defined for capture !");
-                               }
-                               /*Replace soundcard filters by inactive file players or recorders
-                                when placed in recvonly or sendonly mode*/
-                               if (stream->port==0 || stream->dir==SalStreamRecvOnly){
-                                       captcard=NULL;
-                                       playfile=NULL;
-                               }else if (stream->dir==SalStreamSendOnly){
-                                       playcard=NULL;
-                                       captcard=NULL;
-                                       recfile=NULL;
-                                       /*And we will eventually play "playfile" if set by the user*/
-                                       /*playfile=NULL;*/
-                               }
-                               if (send_ringbacktone){
-                                       captcard=NULL;
-                                       playfile=NULL;/* it is setup later*/
-                               }
-                               /*if playfile are supplied don't use soundcards*/
-                               if (lc->use_files) {
-                                       captcard=NULL;
-                                       playcard=NULL;
-                               }
-                               use_ec=captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc);
+
 #if defined(VIDEO_ENABLED)
-                               if (vstream && vstream->dir!=SalStreamInactive && vstream->payloads!=NULL){
-                                       /*when video is used, do not make adaptive rate control on audio, it is stupid.*/
-                                       use_arc_audio=FALSE;
-       #if defined(ANDROID)
-                                       /*On android we have to disable the echo canceller to preserve CPU for video codecs */
-                                       use_ec=FALSE;
-       #endif
-                               }
-#endif
-                               audio_stream_enable_adaptive_bitrate_control(call->audiostream,use_arc_audio);
-                               audio_stream_start_full(
-                                       call->audiostream,
-                                       call->audio_profile,
-                                       stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr,
-                                       stream->port,
-                                       stream->port+1,
-                                       used_pt,
-                                       jitt_comp,
-                                       playfile,
-                                       recfile,
-                                       playcard,
-                                       captcard,
-                                       use_ec
-                                       );
-                               post_configure_audio_streams(call);
-                               if (all_inputs_muted && !send_ringbacktone){
-                                       audio_stream_set_mic_gain(call->audiostream,0);
-                               }
-                               if (stream->dir==SalStreamSendOnly && playfile!=NULL){
-                                       int pause_time=500;
-                                       ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time);
-                               }
-                               if (send_ringbacktone){
-                                       setup_ring_player(lc,call);
-                               }
-                               audio_stream_set_rtcp_information(call->audiostream, cname, tool);
-                       }else ms_warning("No audio stream accepted ?");
-               }
-       }
-#ifdef VIDEO_ENABLED
-       {
-               
-               used_pt=-1;
-               /* shutdown preview */
-               if (lc->previewstream!=NULL) {
-                       video_preview_stop(lc->previewstream);
-                       lc->previewstream=NULL;
-               }
-               call->current_params.has_video=FALSE;
-               if (vstream && vstream->dir!=SalStreamInactive && vstream->port!=0) {
-                       const char *addr=vstream->addr[0]!='\0' ? vstream->addr : call->resultdesc->addr;
-                       call->video_profile=make_profile(call,call->resultdesc,vstream,&used_pt);
-                       if (used_pt!=-1){
-                               VideoStreamDir dir=VideoStreamSendRecv;
-                               MSWebCam *cam=lc->video_conf.device;
-                               bool_t is_inactive=FALSE;
-
-                               call->current_params.has_video=TRUE;
-                               
-                               video_stream_set_sent_video_size(call->videostream,linphone_core_get_preferred_video_size(lc));
-                               video_stream_enable_self_view(call->videostream,lc->video_conf.selfview);
-                               if (lc->video_window_id!=0)
-                                       video_stream_set_native_window_id(call->videostream,lc->video_window_id);
-                               if (lc->preview_window_id!=0)
-                                       video_stream_set_native_preview_window_id (call->videostream,lc->preview_window_id);
-                               video_stream_use_preview_video_window (call->videostream,lc->use_preview_window);
-                               
-                               if (vstream->dir==SalStreamSendOnly && lc->video_conf.capture ){
-                                       cam=get_nowebcam_device();
-                                       dir=VideoStreamSendOnly;
-                               }else if (vstream->dir==SalStreamRecvOnly && lc->video_conf.display ){
-                                       dir=VideoStreamRecvOnly;
-                               }else if (vstream->dir==SalStreamSendRecv){
-                                       if (lc->video_conf.display && lc->video_conf.capture)
-                                               dir=VideoStreamSendRecv;
-                                       else if (lc->video_conf.display)
-                                               dir=VideoStreamRecvOnly;
-                                       else
-                                               dir=VideoStreamSendOnly;
-                               }else{
-                                       ms_warning("video stream is inactive.");
-                                       /*either inactive or incompatible with local capabilities*/
-                                       is_inactive=TRUE;
-                               }
-                               if (call->camera_active==FALSE || all_inputs_muted){
-                                       cam=get_nowebcam_device();
-                               }
-                               if (!is_inactive){
-                                       video_stream_set_direction (call->videostream, dir);
-                                       video_stream_start(call->videostream,
-                                               call->video_profile, addr, vstream->port,
-                                               vstream->port+1,
-                                               used_pt, jitt_comp, cam);
-                                       video_stream_set_rtcp_information(call->videostream, cname,tool);
-                               }
-                       }else ms_warning("No video stream accepted.");
-               }else{
-                       ms_warning("No valid video stream defined.");
-               }
+       if (vstream && vstream->dir!=SalStreamInactive && vstream->payloads!=NULL){
+               /*when video is used, do not make adaptive rate control on audio, it is stupid.*/
+               use_arc=FALSE;
        }
 #endif
+       linphone_call_start_audio_stream(call,cname,all_inputs_muted,send_ringbacktone,use_arc);
+       linphone_call_start_video_stream(call,cname,all_inputs_muted);
+
        call->all_muted=all_inputs_muted;
        call->playing_ringbacktone=send_ringbacktone;
        call->up_bw=linphone_core_get_upload_bandwidth(lc);
@@ -1158,6 +1173,9 @@ void linphone_call_stop_media_streams(LinphoneCall *call){
                        }
                }
                linphone_call_log_fill_stats (call->log,call->audiostream);
+               if (call->endpoint){
+                       linphone_call_remove_from_conf(call);
+               }
                audio_stream_stop(call->audiostream);
                call->audiostream=NULL;
        }
index 6abe85101f78764649486fa5f69d8ab4d16d7aa8..17cb06d9d6498178fc07df3cda84c24a6bae4461 100644 (file)
@@ -2219,13 +2219,20 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){
 int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
        int err=0;
        if (params!=NULL){
+               const char *subject;
                call->params=*params;
                update_local_media_description(lc,call,&call->localdesc);
                call->camera_active=params->has_video;
+
+               if (params->in_conference){
+                       subject="Conference";
+               }else{
+                       subject="Media change";
+               }
                if (lc->vtable.display_status)
                        lc->vtable.display_status(lc,_("Modifying call parameters..."));
                sal_call_set_local_media_description (call->op,call->localdesc);
-               err=sal_call_update(call->op,"Media parameters update");
+               err=sal_call_update(call->op,subject);
        }else{
 #ifdef VIDEO_ENABLED
                if (call->videostream!=NULL){
@@ -2486,8 +2493,7 @@ int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *the_call)
                ms_error("No reason to pause this call, it is already paused or inactive.");
                return -1;
        }
-       if (sal_call_update(call->op,subject) != 0)
-       {
+       if (sal_call_update(call->op,subject) != 0){
                if (lc->vtable.display_warning)
                        lc->vtable.display_warning(lc,_("Could not pause the call"));
        }
@@ -2524,6 +2530,7 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call)
 {
        char temp[255]={0};
        LinphoneCall *call = the_call;
+       const char *subject="Call resuming";
        
        if(call->state!=LinphoneCallPaused ){
                ms_warning("we cannot resume a call that has not been established and paused before");
@@ -2537,7 +2544,8 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call)
        }
        ms_message("Resuming call %p",call);
        sal_media_description_set_dir(call->localdesc,SalStreamSendRecv);
-       if(sal_call_update(call->op,"Call resuming") != 0){
+       if (call->params.in_conference) subject="Resuming conference";
+       if(sal_call_update(call->op,subject) != 0){
                return -1;
        }
        linphone_call_set_state (call,LinphoneCallResuming,"Resuming");
index 010b158514fd2e7f41bde5fc9eb4642db4476f9f..b2b09f855c24ba8e60a0831a966797e17a238514 100644 (file)
@@ -1023,7 +1023,10 @@ bool_t linphone_call_are_all_streams_encrypted(LinphoneCall *call);
 const char* linphone_call_get_authentication_token(LinphoneCall *call);
 bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call);
 
-
+int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call);
+int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call);
+int linphone_core_pause_conference(LinphoneCore *lc);
+int linphone_core_resume_conference(LinphoneCore *lc);
 
 
 #ifdef __cplusplus
index 373079885d994194671bbee8638d6fa771c892fa..e5ce1fd0d367203fce231b1c44bef71abc0f2ad1 100644 (file)
@@ -33,6 +33,7 @@
 #include "config.h"
 #endif
 #include "mediastreamer2/mediastream.h"
+#include "mediastreamer2/msconference.h"
 
 #ifndef LIBLINPHONE_VERSION 
 #define LIBLINPHONE_VERSION LINPHONE_VERSION
@@ -62,7 +63,8 @@ struct _LinphoneCallParams{
        int audio_bw; /* bandwidth limit for audio stream */
        bool_t has_video;
        bool_t real_early_media; /*send real media even during early media (for outgoing calls)*/
-       bool_t pad[2];
+       bool_t in_conference; /*in conference mode */
+       bool_t pad;
 };
 
 struct _LinphoneCall
@@ -87,6 +89,7 @@ struct _LinphoneCall
        int video_port;
        struct _AudioStream *audiostream;  /**/
        struct _VideoStream *videostream;
+       MSAudioEndpoint *endpoint; /*used for conferencing*/
        char *refer_to;
        LinphoneCallParams params;
        LinphoneCallParams current_params;
@@ -99,12 +102,13 @@ struct _LinphoneCall
        bool_t all_muted; /*this flag is set during early medias*/
        bool_t playing_ringbacktone;
        bool_t owns_call_log;
+       bool_t pad;
        OrtpEvQueue *audiostream_app_evq;
-       bool_t audiostream_encrypted;
        char *auth_token;
-       bool_t auth_token_verified;
        OrtpEvQueue *videostream_app_evq;
        bool_t videostream_encrypted;
+       bool_t audiostream_encrypted;
+       bool_t auth_token_verified;
 };
 
 
@@ -388,6 +392,13 @@ typedef struct autoreplier_config
        const char *message;            /* the path of the file to be played */
 }autoreplier_config_t;
 
+struct _LinphoneConference{
+       MSAudioConference *conf;
+       AudioStream *local_participant;
+       MSAudioEndpoint *local_endpoint;
+};
+
+typedef struct _LinphoneConference LinphoneConference;
 
 struct _LinphoneCore
 {
@@ -439,6 +450,8 @@ struct _LinphoneCore
        time_t netup_time; /*time when network went reachable */
        struct _EcCalibrator *ecc;
        MSList *hooks;
+       LinphoneConference conf_ctx;
+       char* zrtp_secrets_cache;
        bool_t use_files;
        bool_t apply_nat_settings;
        bool_t initial_subscribes_sent;
@@ -448,7 +461,6 @@ struct _LinphoneCore
        bool_t network_reachable;
        bool_t use_preview_window;
        bool_t ringstream_autorelease;
-       char* zrtp_secrets_cache;
 };
 
 bool_t linphone_core_can_we_add_call(LinphoneCore *lc);
@@ -493,6 +505,10 @@ void ec_calibrator_destroy(EcCalibrator *ecc);
 
 void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapsed);
 
+/*conferencing subsystem*/
+void linphone_call_add_to_conf(LinphoneCall *call);
+void linphone_call_remove_from_conf(LinphoneCall *call);
+
 #define HOLD_OFF       (0)
 #define HOLD_ON                (1)
 
index a82dcdbf8a4e8364bdcaa6f6fb88ca087f48a780..a8ca8f204ca57d18f6e1c0515adaf7edb0c905dd 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a82dcdbf8a4e8364bdcaa6f6fb88ca087f48a780
+Subproject commit a8ca8f204ca57d18f6e1c0515adaf7edb0c905dd