forked from mirrors/linphone-iphone
wip - conferencing
This commit is contained in:
parent
1caf08c596
commit
98c4a9bb5e
7 changed files with 316 additions and 162 deletions
|
|
@ -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
|
||||
|
|
|
|||
108
coreapi/conference.c
Normal file
108
coreapi/conference.c
Normal file
|
|
@ -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,¶ms);
|
||||
}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;
|
||||
}
|
||||
|
||||
|
|
@ -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 ?");
|
||||
}
|
||||
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;
|
||||
}
|
||||
#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;
|
||||
#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->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.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit a82dcdbf8a4e8364bdcaa6f6fb88ca087f48a780
|
||||
Subproject commit a8ca8f204ca57d18f6e1c0515adaf7edb0c905dd
|
||||
Loading…
Add table
Reference in a new issue