Commit 25836693 authored by jehan's avatar jehan
Browse files

implement re-invite from multicast to unicast call.

parent d285a55c
......@@ -235,6 +235,21 @@ void linphone_call_params_unref(LinphoneCallParams *cp) {
belle_sip_object_unref(cp);
}
void linphone_call_params_enable_audio_multicast(LinphoneCallParams *params, bool_t yesno) {
params->audio_multicast_enabled=yesno;
}
bool_t linphone_call_params_audio_multicast_enabled(const LinphoneCallParams *params) {
return params->audio_multicast_enabled;
}
void linphone_call_params_enable_video_multicast(LinphoneCallParams *params, bool_t yesno) {
params->video_multicast_enabled=yesno;
}
bool_t linphone_call_params_video_multicast_enabled(const LinphoneCallParams *params) {
return params->video_multicast_enabled;
}
/*******************************************************************************
* Constructor and destructor functions *
******************************************************************************/
......
......@@ -322,6 +322,42 @@ LINPHONE_PUBLIC LinphoneCallParams * linphone_call_params_ref(LinphoneCallParams
LINPHONE_PUBLIC void linphone_call_params_unref(LinphoneCallParams *cp);
/**
* Use to enable multicast rtp for audio stream.
* * If enabled, outgoing calls put a multicast address from #linphone_core_get_video_multicast_addr into audio cline. In case of outgoing call audio stream is sent to this multicast address.
* <br> For incoming calls behavior is unchanged.
* @param core #LinphoneCallParams
* @param yesno if yes, subsequent calls will propose multicast ip set by #linphone_core_set_audio_multicast_addr
* @ingroup media_parameters
**/
LINPHONE_PUBLIC void linphone_call_params_enable_audio_multicast(LinphoneCallParams *param, bool_t yesno);
/**
* Use to get multicast state of audio stream.
* @param core #LinphoneCallParams
* @return true if subsequent calls will propose multicast ip set by #linphone_core_set_audio_multicast_addr
* @ingroup media_parameters
**/
LINPHONE_PUBLIC bool_t linphone_call_params_audio_multicast_enabled(const LinphoneCallParams *param);
/**
* Use to enable multicast rtp for video stream.
* If enabled, outgoing calls put a multicast address from #linphone_core_get_video_multicast_addr into video cline. In case of outgoing call video stream is sent to this multicast address.
* <br> For incoming calls behavior is unchanged.
* @param core #LinphoneCallParams
* @param yesno if yes, subsequent outgoing calls will propose multicast ip set by #linphone_core_set_video_multicast_addr
* @ingroup media_parameters
**/
LINPHONE_PUBLIC void linphone_call_params_enable_video_multicast(LinphoneCallParams *param, bool_t yesno);
/**
* Use to get multicast state of video stream.
* @param core #LinphoneCallParams
* @return true if subsequent calls will propose multicast ip set by #linphone_core_set_video_multicast_addr
* @ingroup media_parameters
**/
LINPHONE_PUBLIC bool_t linphone_call_params_video_multicast_enabled(const LinphoneCallParams *param);
/*******************************************************************************
* DEPRECATED *
******************************************************************************/
......
......@@ -144,10 +144,13 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
call->resultdesc=new_md;
if ((call->audiostream && call->audiostream->ms.state==MSStreamStarted) || (call->videostream && call->videostream->ms.state==MSStreamStarted)){
clear_early_media_destinations(call);
int md_changed=0;
/* we already started media: check if we really need to restart it*/
if (oldmd){
int md_changed = media_parameters_changed(call, oldmd, new_md);
if ((md_changed & (SAL_MEDIA_DESCRIPTION_CODEC_CHANGED|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED))){
md_changed = media_parameters_changed(call, oldmd, new_md);
if ((md_changed & ( SAL_MEDIA_DESCRIPTION_CODEC_CHANGED
|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED
|SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED))){
ms_message("Media descriptions are different, need to restart the streams.");
} else if ( call->playing_ringbacktone) {
ms_message("Playing ringback tone, will restart the streams.");
......@@ -181,6 +184,11 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
}
}
linphone_call_stop_media_streams (call);
if (md_changed & SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED){
ms_message("Media ip type has changed, destroying sessions context on call [%p]",call);
ms_media_stream_sessions_uninit(&call->sessions[0]);
ms_media_stream_sessions_uninit(&call->sessions[1]);
}
linphone_call_init_media_streams (call);
}
......
......@@ -591,12 +591,12 @@ void linphone_call_make_local_media_description_with_params(LinphoneCore *lc, Li
CodecConstraints codec_hints={0};
/*multicast is only set in case of outgoing call*/
if (call->dir == LinphoneCallOutgoing && linphone_core_audio_multicast_enabled(lc)) {
if (call->dir == LinphoneCallOutgoing && linphone_call_params_audio_multicast_enabled(params)) {
md->streams[0].ttl=linphone_core_get_audio_multicast_ttl(lc);
md->streams[0].multicast_role = SalMulticastSender;
}
if (call->dir == LinphoneCallOutgoing && linphone_core_video_multicast_enabled(lc)) {
if (call->dir == LinphoneCallOutgoing && linphone_call_params_video_multicast_enabled(params)) {
md->streams[1].ttl=linphone_core_get_video_multicast_ttl(lc);
md->streams[1].multicast_role = SalMulticastSender;
}
......@@ -814,17 +814,6 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from,
linphone_core_get_video_port_range(call->core, &min_port, &max_port);
port_config_set(call,1,min_port,max_port);
if (call->dir==LinphoneCallOutgoing){
if ( linphone_core_audio_multicast_enabled(call->core)){
strncpy(call->media_ports[0].multicast_ip,
linphone_core_get_audio_multicast_addr(call->core), sizeof(call->media_ports[0].multicast_ip));
}
if ( linphone_core_video_multicast_enabled(call->core)){
strncpy(call->media_ports[1].multicast_ip,
linphone_core_get_video_multicast_addr(call->core), sizeof(call->media_ports[1].multicast_ip));
}
}
linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO], LINPHONE_CALL_STATS_AUDIO);
linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO], LINPHONE_CALL_STATS_VIDEO);
#ifdef VIDEO_ENABLED
......@@ -944,7 +933,19 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneCall, belle_sip_object_t,
NULL, // marshal
FALSE
);
void linphone_call_fill_media_multicast_addr(LinphoneCall *call) {
if (linphone_call_params_audio_multicast_enabled(call->params)){
strncpy(call->media_ports[0].multicast_ip,
linphone_core_get_audio_multicast_addr(call->core), sizeof(call->media_ports[0].multicast_ip));
} else
call->media_ports[0].multicast_ip[0]='\0';
if (linphone_call_params_video_multicast_enabled(call->params)){
strncpy(call->media_ports[1].multicast_ip,
linphone_core_get_video_multicast_addr(call->core), sizeof(call->media_ports[1].multicast_ip));
} else
call->media_ports[1].multicast_ip[0]='\0';
}
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg){
LinphoneCall *call = belle_sip_object_new(LinphoneCall);
......@@ -955,6 +956,8 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
linphone_call_init_common(call,from,to);
call->params = linphone_call_params_copy(params);
linphone_call_fill_media_multicast_addr(call);
if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) {
call->ice_session = ice_session_new();
/*for backward compatibility purposes, shall be enabled by default in futur*/
......@@ -1010,26 +1013,18 @@ void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, c
call->params->media_encryption = LinphoneMediaEncryptionNone;
}
/* set both local audio & video multicast ip address if any*/
for (i=0;i<2;++i){
if (md->streams[i].rtp_addr[i]!='\0' && ms_is_multicast(md->streams[i].rtp_addr)) {
strncpy(call->media_ports[i].multicast_ip,md->streams[i].rtp_addr,sizeof(call->media_ports[i].multicast_ip));
ms_message("Disabling rtcp on call [%p], stream [%i] because of multicast",call,i);
call->media_ports[i].mcast_rtp_port=md->streams[i].rtp_port;
call->media_ports[i].mcast_rtcp_port=0;
}
}
}
LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){
LinphoneCall *call = belle_sip_object_new(LinphoneCall);
const SalMediaDescription *md;
SalMediaDescription *md;
LinphoneFirewallPolicy fpol;
call->dir=LinphoneCallIncoming;
sal_op_set_user_pointer(op,call);
call->op=op;
call->core=lc;
int i;
linphone_call_incoming_select_ip_version(call);
sal_op_cnx_ip_to_0000_if_sendonly_enable(op,lp_config_get_default_int(lc->config,"sip","cnx_ip_to_0000_if_sendonly_enabled",0));
......@@ -1075,7 +1070,14 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
// It is licit to receive an INVITE without SDP
// In this case WE chose the media parameters according to policy.
linphone_call_set_compatible_incoming_call_parameters(call, md);
/* set multicast role & address if any*/
for (i=0;i<md->nb_streams;i++){
if (!sal_call_is_offerer(op) && ms_is_multicast(md->streams[i].rtp_addr))
md->streams[i].multicast_role = SalMulticastReceiver;
strncpy(call->media_ports[i].multicast_ip,md->streams[i].rtp_addr,sizeof(call->media_ports[i].multicast_ip));
}
}
fpol=linphone_core_get_firewall_policy(call->core);
/*create the ice session now if ICE is required*/
if (fpol==LinphonePolicyUseIce){
......@@ -1478,10 +1480,23 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){
call->current_params->avpf_rr_interval = 0;
}
if (md){
const char *rtp_addr;
SalStreamDescription *sd=sal_media_description_find_best_stream(md,SalAudio);
call->current_params->audio_dir=sd ? media_direction_from_sal_stream_dir(sd->dir) : LinphoneMediaDirectionInactive;
if (call->current_params->audio_dir != LinphoneMediaDirectionInactive) {
rtp_addr = sd->rtp_addr[0]!='\0' ? sd->rtp_addr : call->resultdesc->addr;
call->current_params->audio_multicast_enabled = ms_is_multicast(rtp_addr);
} else
call->current_params->audio_multicast_enabled = FALSE;
sd=sal_media_description_find_best_stream(md,SalVideo);
call->current_params->video_dir=sd ? media_direction_from_sal_stream_dir(sd->dir) : LinphoneMediaDirectionInactive;
if (call->current_params->video_dir != LinphoneMediaDirectionInactive) {
rtp_addr = sd->rtp_addr[0]!='\0' ? sd->rtp_addr : call->resultdesc->addr;
call->current_params->video_multicast_enabled = ms_is_multicast(rtp_addr);
} else
call->current_params->video_multicast_enabled = FALSE;
}
return call->current_params;
......@@ -1900,9 +1915,38 @@ int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer){
/*eventually join to a multicast group if told to do so*/
static void linphone_call_join_multicast_group(LinphoneCall *call, int stream_index, MediaStream *ms){
if (call->media_ports[stream_index].multicast_ip[stream_index]!='\0' && call->media_ports[stream_index].mcast_rtp_port!=0){
if (call->media_ports[stream_index].multicast_ip[stream_index]!='\0'){
media_stream_join_multicast_group(ms, call->media_ports[stream_index].multicast_ip);
}
} else
ms_error("Cannot join multicast group if multicast ip is not set for call [%p]",call);
}
static SalMulticastRole linphone_call_get_multicast_role(const LinphoneCall *call,SalStreamType type) {
SalMulticastRole multicast_role=SalMulticastInactive;
SalMediaDescription *remotedesc, *localdesc;
SalStreamDescription *stream_desc = NULL;
if (!call->op) goto end;
remotedesc = sal_call_get_remote_media_description(call->op);
localdesc = call->localdesc;
if (!localdesc && !remotedesc && call->dir == LinphoneCallOutgoing) {
/*well using call dir*/
if ((type == SalAudio && linphone_call_params_audio_multicast_enabled(call->params))
|| (type == SalVideo && linphone_call_params_video_multicast_enabled(call->params)))
multicast_role=SalMulticastSender;
} else if (localdesc && (!remotedesc || sal_call_is_offerer(call->op))) {
stream_desc = sal_media_description_find_best_stream(localdesc, type);
} else if (!sal_call_is_offerer(call->op) && remotedesc)
stream_desc = sal_media_description_find_best_stream(remotedesc, type);
if (stream_desc)
multicast_role=stream_desc->multicast_role;
else
ms_message("Cannot determine multicast role for stream type [%s] on call [%p]",sal_stream_type_to_string(type),call);
end:
return multicast_role;
}
void linphone_call_init_audio_stream(LinphoneCall *call){
......@@ -1913,14 +1957,23 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
char rtcp_tool[128]={0};
char* cname;
snprintf(rtcp_tool,sizeof(rtcp_tool)-1,"%s-%s",linphone_core_get_user_agent_name(),linphone_core_get_user_agent_version());
if (call->audiostream != NULL) return;
if (call->sessions[0].rtp_session==NULL){
SalMulticastRole multicast_role = linphone_call_get_multicast_role(call,SalAudio);
SalMediaDescription *remotedesc=NULL;
SalStreamDescription *stream_desc = NULL;
if (call->op) remotedesc = sal_call_get_remote_media_description(call->op);
if (remotedesc)
stream_desc = sal_media_description_find_best_stream(remotedesc, SalAudio);
call->audiostream=audiostream=audio_stream_new2(linphone_call_get_bind_ip_for_stream(call,0),
call->media_ports[0].mcast_rtp_port ? call->media_ports[0].mcast_rtp_port : call->media_ports[0].rtp_port,
call->media_ports[0].mcast_rtcp_port ? call->media_ports[0].mcast_rtcp_port : call->media_ports[0].rtcp_port);
linphone_call_join_multicast_group(call, 0, &audiostream->ms);
multicast_role == SalMulticastReceiver ? stream_desc->rtp_port : call->media_ports[0].rtp_port,
multicast_role == SalMulticastReceiver ? 0 /*disabled for now*/ : call->media_ports[0].rtcp_port);
if (multicast_role == SalMulticastReceiver)
linphone_call_join_multicast_group(call, 0, &audiostream->ms);
rtp_session_enable_network_simulation(call->audiostream->ms.sessions.rtp_session, &lc->net_conf.netsim_params);
cname = linphone_address_as_string_uri_only(call->me);
audio_stream_set_rtcp_information(call->audiostream, cname, rtcp_tool);
......@@ -2014,11 +2067,14 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
_linphone_call_prepare_ice_for_stream(call,0,FALSE);
}
void linphone_call_init_video_stream(LinphoneCall *call){
#ifdef VIDEO_ENABLED
LinphoneCore *lc=call->core;
char* cname;
char rtcp_tool[128];
snprintf(rtcp_tool,sizeof(rtcp_tool)-1,"%s-%s",linphone_core_get_user_agent_name(),linphone_core_get_user_agent_version());
if (call->videostream == NULL){
......@@ -2027,10 +2083,18 @@ void linphone_call_init_video_stream(LinphoneCall *call){
const char *display_filter=linphone_core_get_video_display_filter(lc);
if (call->sessions[1].rtp_session==NULL){
SalMulticastRole multicast_role = linphone_call_get_multicast_role(call,SalVideo);
SalMediaDescription *remotedesc=NULL;
SalStreamDescription *stream_desc = NULL;
if (call->op) remotedesc = sal_call_get_remote_media_description(call->op);
if (remotedesc)
stream_desc = sal_media_description_find_best_stream(remotedesc, SalVideo);
call->videostream=video_stream_new2(linphone_call_get_bind_ip_for_stream(call,1),
call->media_ports[1].mcast_rtp_port>0 ? call->media_ports[1].mcast_rtp_port : call->media_ports[1].rtp_port,
call->media_ports[1].mcast_rtcp_port>0 ? call->media_ports[1].mcast_rtcp_port : call->media_ports[1].rtcp_port);
linphone_call_join_multicast_group(call, 1, &call->videostream->ms);
multicast_role == SalMulticastReceiver ? stream_desc->rtp_port : call->media_ports[1].rtp_port,
multicast_role == SalMulticastReceiver ? 0 /*disabled for now*/ : call->media_ports[1].rtcp_port);
if (multicast_role == SalMulticastReceiver)
linphone_call_join_multicast_group(call, 1, &call->videostream->ms);
rtp_session_enable_network_simulation(call->videostream->ms.sessions.rtp_session, &lc->net_conf.netsim_params);
cname = linphone_address_as_string_uri_only(call->me);
video_stream_set_rtcp_information(call->videostream, cname, rtcp_tool);
......
......@@ -3436,6 +3436,8 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){
int err;
bool_t no_user_consent=call->params->no_user_consent;
linphone_call_fill_media_multicast_addr(call);
if (!no_user_consent) linphone_call_make_local_media_description(lc,call);
#ifdef BUILD_UPNP
if(call->upnp_session != NULL) {
......@@ -3651,6 +3653,11 @@ int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, cons
}
if (params==NULL){
linphone_call_params_enable_video(call->params, lc->video_policy.automatically_accept || call->current_params->has_video);
if (!sal_call_is_offerer(call->op)) {
/*reset call param for multicast because this param is only relevant when offering*/
linphone_call_params_enable_audio_multicast(call->params,FALSE);
linphone_call_params_enable_video_multicast(call->params,FALSE);
}
}else
linphone_call_set_new_params(call,params);
......@@ -3662,6 +3669,9 @@ int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, cons
ms_warning("Video isn't supported in conference");
call->params->has_video = FALSE;
}
/*update multicast params according to call params*/
linphone_call_fill_media_multicast_addr(call);
linphone_call_init_media_streams(call); /*so that video stream is initialized if necessary*/
if (call->ice_session != NULL) {
if (linphone_call_prepare_ice(call,TRUE)==1)
......@@ -7053,6 +7063,8 @@ void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *para
params->audio_dir=LinphoneMediaDirectionSendRecv;
params->video_dir=LinphoneMediaDirectionSendRecv;
params->real_early_media=lp_config_get_int(lc->config,"misc","real_early_media",FALSE);
params->audio_multicast_enabled=linphone_core_audio_multicast_enabled(lc);
params->video_multicast_enabled=linphone_core_video_multicast_enabled(lc);
}
void linphone_core_set_device_identifier(LinphoneCore *lc,const char* device_id) {
......
......@@ -3631,6 +3631,19 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_getVideoEnable
return (jboolean)linphone_call_params_video_enabled((LinphoneCallParams*)lcp);
}
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableVideoMulticast(JNIEnv *env, jobject thiz, jlong lcp, jboolean b){
linphone_call_params_enable_video_multicast((LinphoneCallParams*)lcp, b);
}
extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_videoMulticastEnabled(JNIEnv *env, jobject thiz, jlong lcp){
return (jboolean)linphone_call_params_video_multicast_enabled((LinphoneCallParams*)lcp);
}
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableAudioMulticast(JNIEnv *env, jobject thiz, jlong lcp, jboolean b){
linphone_call_params_enable_audio_multicast((LinphoneCallParams*)lcp, b);
}
extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_audioMulticastEnabled(JNIEnv *env, jobject thiz, jlong lcp){
return (jboolean)linphone_call_params_audio_multicast_enabled((LinphoneCallParams*)lcp);
}
extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_localConferenceMode(JNIEnv *env, jobject thiz, jlong lcp){
return (jboolean)linphone_call_params_get_local_conference_mode((LinphoneCallParams*)lcp);
}
......
......@@ -112,7 +112,8 @@ struct _LinphoneCallParams{
LinphoneMediaDirection video_dir;
bool_t video_declined; /*use to keep traces of declined video to avoid to re-offer video in case of automatic RE-INVITE*/
bool_t internal_call_update; /*use mark that call update was requested internally (might be by ice)*/
bool_t video_multicast_enabled;
bool_t audio_multicast_enabled;
};
BELLE_SIP_DECLARE_VPTR(LinphoneCallParams);
......@@ -205,8 +206,6 @@ typedef struct StunCandidate{
typedef struct _PortConfig{
char multicast_ip[LINPHONE_IPADDR_SIZE];
int mcast_rtp_port;
int mcast_rtcp_port;
int rtp_port;
int rtcp_port;
}PortConfig;
......@@ -859,6 +858,7 @@ void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const
void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call);
void linphone_call_make_local_media_description_with_params(LinphoneCore *lc, LinphoneCall *call, LinphoneCallParams *params);
void linphone_call_increment_local_media_description(LinphoneCall *call);
void linphone_call_fill_media_multicast_addr(LinphoneCall *call);
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md);
bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit);
......
......@@ -307,6 +307,8 @@ int sal_stream_description_equals(const SalStreamDescription *sd1, const SalStre
if (sd1->type != sd2->type) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
if (strcmp(sd1->rtp_addr, sd2->rtp_addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
if (sd1->rtp_addr[0]!='\0' && sd2->rtp_addr[0]!='\0' && ms_is_multicast(sd1->rtp_addr) != ms_is_multicast(sd2->rtp_addr))
result |= SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED;
if (sd1->rtp_port != sd2->rtp_port) {
if ((sd1->rtp_port == 0) || (sd2->rtp_port == 0)) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
else result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
......@@ -330,6 +332,8 @@ int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaD
int i;
if (strcmp(md1->addr, md2->addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
if (md1->addr[0]!='\0' && md2->addr[0]!='\0' && ms_is_multicast(md1->addr) != ms_is_multicast(md2->addr))
result |= SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED;
if (md1->nb_streams != md2->nb_streams) result |= SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED;
if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
for(i = 0; i < md1->nb_streams; ++i){
......
......@@ -68,15 +68,20 @@ typedef enum {
SalTransportDTLS, /*DTLS*/
}SalTransport;
#define SAL_MEDIA_DESCRIPTION_UNCHANGED 0x00
#define SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED (1)
#define SAL_MEDIA_DESCRIPTION_CODEC_CHANGED (1<<1)
#define SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED (1<<2)
#define SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED (1<<3)
#define SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED (1<<4)
#define SAL_MEDIA_DESCRIPTION_CHANGED (SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED | SAL_MEDIA_DESCRIPTION_CODEC_CHANGED |\
SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED |SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED | SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)
#define SAL_MEDIA_DESCRIPTION_UNCHANGED 0x00
#define SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED (1)
#define SAL_MEDIA_DESCRIPTION_CODEC_CHANGED (1<<1)
#define SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED (1<<2)
#define SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED (1<<3)
#define SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED (1<<4)
#define SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED (1<<5) /* use to notify when switching from multicast to unicast*/
#define SAL_MEDIA_DESCRIPTION_CHANGED (SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED \
|SAL_MEDIA_DESCRIPTION_CODEC_CHANGED \
|SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED \
|SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED \
|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED \
|SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED)
const char* sal_transport_to_string(SalTransport transport);
SalTransport sal_transport_parse(const char*);
......
......@@ -131,4 +131,31 @@ public interface LinphoneCallParams {
* @return The received video size.
*/
VideoSize getReceivedVideoSize();
/**
* Use to enable multicast rtp for audio stream.
* * If enabled, outgoing calls put a multicast address from #linphone_core_get_video_multicast_addr into audio cline. In case of outgoing call audio stream is sent to this multicast address.
* <br> For incoming calls behavior is unchanged.
* @param yesno if yes, subsequent calls will propose multicast ip set by LinphoneCore.setAudioMulticastAddr
**/
void enableAudioMulticast(boolean yesno);
/**
* Use to get multicast state of audio stream.
* @return true if subsequent calls will propose multicast ip set by LinphoneCore.setAudioMulticastAddr
**/
boolean audioMulticastEnabled();
/**
* Use to enable multicast rtp for video stream.
* If enabled, outgoing calls put a multicast address from #linphone_core_get_video_multicast_addr into video cline. In case of outgoing call video stream is sent to this multicast address.
* <br> For incoming calls behavior is unchanged.
* @param yesno if yes, subsequent outgoing calls will propose multicast ip set by LinphoneCore.setVideoMulticastAddr
**/
void enableVideoMulticast(boolean yesno);
/**
* Use to get multicast state of video stream.
* @return true if subsequent calls will propose multicast ip set by LinphoneCore.setVideoMulticastAddr
**/
boolean videoMulticastEnabled();
}
......@@ -150,4 +150,25 @@ public class LinphoneCallParamsImpl implements LinphoneCallParams {
vSize.height = nativeSize[1];
return vSize;
}
private native void enableAudioMulticast(long ptr,boolean yesno);
@Override
public void enableAudioMulticast(boolean yesno) {
enableAudioMulticast(nativePtr,yesno);
}
private native boolean audioMulticastEnabled(long ptr);
@Override
public boolean audioMulticastEnabled() {
return audioMulticastEnabled(nativePtr);
}
private native void enableVideoMulticast(long ptr,boolean yesno);
@Override
public void enableVideoMulticast(boolean yesno) {
enableVideoMulticast(nativePtr,yesno);
}
private native boolean videoMulticastEnabled(long ptr);
@Override
public boolean videoMulticastEnabled() {
return videoMulticastEnabled(nativePtr);
}
}
......@@ -3086,7 +3086,7 @@ static void multiple_early_media(void) {
linphone_core_manager_destroy(pauline);
}
static void check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, MSList* lcs,LinphoneMediaDirection audio_dir, LinphoneMediaDirection video_dir) {
void check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, MSList* lcs,LinphoneMediaDirection audio_dir, LinphoneMediaDirection video_dir) {
CU_ASSERT_PTR_NOT_NULL(call);
if (call) {
int current_recv_iframe = mgr->stat.number_of_IframeDecoded;
......
......@@ -308,6 +308,7 @@ void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_r
bool_t call_with_caller_params(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr, const LinphoneCallParams *params);
bool_t pause_call_1(LinphoneCoreManager* mgr_1,LinphoneCall* call_1,LinphoneCoreManager* mgr_2,LinphoneCall* call_2);
bool_t compare_files(const char *path1, const char *path2);
void check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, MSList* lcs,LinphoneMediaDirection audio_dir, LinphoneMediaDirection video_dir);
static const int audio_cmp_min_overlap=90;
......
......@@ -96,6 +96,7 @@ static void early_media_with_multicast_base(bool_t video) {
int begin;
LinphoneVideoPolicy marie_policy, pauline_policy;
LpConfig *marie_lp;
LinphoneCallParams *params;
belle_sip_object_enable_leak_detector(TRUE);
begin=belle_sip_object_get_object_count();
......@@ -172,6 +173,12 @@ static void early_media_with_multicast_base(bool_t video) {
CU_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline2->lc))->download_bandwidth>70);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline2->lc))->download_bandwidth<90);
CU_ASSERT_TRUE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))));
CU_ASSERT_TRUE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))));
if (video) {
CU_ASSERT_TRUE(linphone_call_params_video_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))));
CU_ASSERT_TRUE(linphone_call_params_video_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))));
}
if (video) {
CU_ASSERT_TRUE( wait_for_list(lcs,&pauline->stat.number_of_IframeDecoded,1,2000));
......@@ -182,13 +189,48 @@ static void early_media_with_multicast_base(bool_t video) {
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallConnected, 1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline2->stat.number_of_LinphoneCallEnd, 1,1000));
CU_ASSERT_TRUE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))));
CU_ASSERT_TRUE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))));
if (video) {
CU_ASSERT_TRUE(linphone_call_params_video_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))));
CU_ASSERT_TRUE(linphone_call_params_video_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))));
}
params=linphone_call_params_copy(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)));
linphone_call_params_enable_audio_multicast(params,FALSE);
linphone_call_params_enable_video_multicast(params,FALSE);
linphone_core_enable_video_capture(pauline->lc, TRUE);
linphone_core_enable_video_display(pauline->lc, TRUE);
linphone_core_enable_video_capture(marie->lc, TRUE);
linphone_core_enable_video_display(marie->lc, TRUE);
linphone_core_update_call( pauline->lc
, linphone_core_get_current_call(pauline->lc)
, linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)));
, params);
linphone_call_params_destroy(params);
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2,1000));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 2,1000));
CU_ASSERT_FALSE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))));
CU_ASSERT_FALSE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))));
check_media_direction( pauline