implement edge detection, and automatic configuration of call parameters for low bitrates

This commit is contained in:
Simon Morlat 2012-09-04 22:02:34 +02:00
parent f75692eb02
commit 5e4ac070cc
7 changed files with 51 additions and 45 deletions

View file

@ -207,7 +207,10 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
md->nstreams=1;
strncpy(md->addr,call->localip,sizeof(md->addr));
strncpy(md->username,username,sizeof(md->username));
md->bandwidth=linphone_core_get_download_bandwidth(lc);
if (call->params.down_bw)
md->bandwidth=call->params.down_bw;
else md->bandwidth=linphone_core_get_download_bandwidth(lc);
/*set audio capabilities */
strncpy(md->streams[0].rtp_addr,call->localip,sizeof(md->streams[0].rtp_addr));
@ -217,7 +220,10 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
md->streams[0].proto=(call->params.media_encryption == LinphoneMediaEncryptionSRTP) ?
SalProtoRtpSavp : SalProtoRtpAvp;
md->streams[0].type=SalAudio;
md->streams[0].ptime=lc->net_conf.down_ptime;
if (call->params.down_ptime)
md->streams[0].ptime=call->params.down_ptime;
else
md->streams[0].ptime=lc->net_conf.down_ptime;
l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw,&md->streams[0].max_rate);
pt=payload_type_clone(rtp_profile_get_payload_from_mime(&av_profile,"telephone-event"));
l=ms_list_append(l,pt);
@ -320,6 +326,21 @@ void linphone_call_init_stats(LinphoneCallStats *stats, int type) {
stats->sent_rtcp = NULL;
}
static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){
if (ac->port!=0){
strcpy(md->streams[0].rtp_addr,ac->addr);
md->streams[0].rtp_port=ac->port;
if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || md->nstreams==1){
strcpy(md->addr,ac->addr);
}
}
if (vc->port!=0){
strcpy(md->streams[1].rtp_addr,vc->addr);
md->streams[1].rtp_port=vc->port;
}
}
static void discover_mtu(LinphoneCore *lc, const char *remote){
int mtu;
if (lc->net_conf.mtu==0 ){
@ -333,16 +354,12 @@ static void discover_mtu(LinphoneCore *lc, const char *remote){
}
}
static void update_sal_media_description_from_params(SalMediaDescription *md, const LinphoneCallParams *params){
if (params->down_bw)
md->bandwidth=params->down_bw;
if (params->down_ptime)
md->streams[0].ptime=params->down_ptime;
}
#define STUN_CANDIDATE_INIT {{0},0}
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params)
{
LinphoneCall *call=ms_new0(LinphoneCall,1);
StunCandidate ac=STUN_CANDIDATE_INIT,vc=STUN_CANDIDATE_INIT;
int ping_time=-1;
call->dir=LinphoneCallOutgoing;
call->op=sal_op_new(lc->sal);
@ -355,15 +372,16 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
call->ice_session = ice_session_new();
ice_session_set_role(call->ice_session, IR_Controlling);
}
call->localdesc=create_local_media_description (lc,call);
call->camera_active=params->has_video;
if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseStun) {
ping_time=linphone_core_run_stun_tests(call->core,call);
ping_time=linphone_core_run_stun_tests(call->core,call,&ac, &vc);
}
if (ping_time>=0) {
linphone_core_adapt_to_network(lc,ping_time,&call->params);
update_sal_media_description_from_params(call->localdesc,&call->params);
}
call->localdesc=create_local_media_description(lc,call);
update_media_description_from_stun(call->localdesc,&ac,&vc);
call->camera_active=params->has_video;
discover_mtu(lc,linphone_address_get_domain (to));
if (params->referer){
sal_call_set_referer(call->op,params->referer->op);
@ -376,6 +394,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
LinphoneCall *call=ms_new0(LinphoneCall,1);
char *from_str;
int ping_time=-1;
StunCandidate ac=STUN_CANDIDATE_INIT,vc=STUN_CANDIDATE_INIT;
call->dir=LinphoneCallIncoming;
sal_op_set_user_pointer(op,call);
@ -398,8 +417,6 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
linphone_call_init_common(call, from, to);
linphone_core_init_default_params(lc, &call->params);
call->params.has_video &= !!lc->video_policy.automatically_accept;
call->localdesc=create_local_media_description(lc,call);
call->camera_active=call->params.has_video;
switch (linphone_core_get_firewall_policy(call->core)) {
case LinphonePolicyUseIce:
call->ice_session = ice_session_new();
@ -416,15 +433,18 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
}
break;
case LinphonePolicyUseStun:
ping_time=linphone_core_run_stun_tests(call->core,call);
ping_time=linphone_core_run_stun_tests(call->core,call,&ac, &vc);
/* No break to also destroy ice session in this case. */
default:
break;
}
if (ping_time>=0) {
linphone_core_adapt_to_network(lc,ping_time,&call->params);
update_sal_media_description_from_params(call->localdesc,&call->params);
};
call->localdesc=create_local_media_description(lc,call);
update_media_description_from_stun(call->localdesc,&ac,&vc);
call->camera_active=call->params.has_video;
discover_mtu(lc,linphone_address_get_domain(from));
return call;
}
@ -953,11 +973,10 @@ void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, Lin
void linphone_call_init_audio_stream(LinphoneCall *call){
LinphoneCore *lc=call->core;
SalMediaDescription *md=call->localdesc;
AudioStream *audiostream;
int dscp=lp_config_get_int(lc->config,"rtp","audio_dscp",-1);
call->audiostream=audiostream=audio_stream_new(md->streams[0].rtp_port,md->streams[0].rtcp_port,linphone_core_ipv6_enabled(lc));
call->audiostream=audiostream=audio_stream_new(call->audio_port,call->audio_port+1,linphone_core_ipv6_enabled(lc));
if (dscp!=-1)
audio_stream_set_dscp(audiostream,dscp);
if (linphone_core_echo_limiter_enabled(lc)){
@ -1006,13 +1025,12 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
void linphone_call_init_video_stream(LinphoneCall *call){
#ifdef VIDEO_ENABLED
LinphoneCore *lc=call->core;
SalMediaDescription *md=call->localdesc;
if ((lc->video_conf.display || lc->video_conf.capture) && md->streams[1].rtp_port>0){
if ((lc->video_conf.display || lc->video_conf.capture) && call->params.has_video){
int video_recv_buf_size=lp_config_get_int(lc->config,"video","recv_buf_size",0);
int dscp=lp_config_get_int(lc->config,"rtp","video_dscp",-1);
call->videostream=video_stream_new(md->streams[1].rtp_port,md->streams[1].rtcp_port,linphone_core_ipv6_enabled(lc));
call->videostream=video_stream_new(call->video_port,call->video_port+1,linphone_core_ipv6_enabled(lc));
if (dscp!=-1)
video_stream_set_dscp(call->videostream,dscp);
video_stream_enable_display_filter_auto_rotate(call->videostream, lp_config_get_int(lc->config,"video","display_filter_auto_rotate",0));

View file

@ -467,7 +467,7 @@ static int recvStunResponse(ortp_socket_t sock, char *ipaddr, int *port, int *id
}
/* this functions runs a simple stun test and return the number of milliseconds to complete the tests, or -1 if the test were failed.*/
int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call, StunCandidate *ac, StunCandidate *vc){
const char *server=linphone_core_get_stun_server(lc);
if (lc->sip_conf.ipv6_enabled){
@ -483,13 +483,9 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
bool_t got_audio,got_video;
bool_t cone_audio=FALSE,cone_video=FALSE;
struct timeval init,cur;
SalEndpointCandidate *ac,*vc;
double elapsed;
int ret=0;
ac=&call->localdesc->streams[0].candidates[0];
vc=&call->localdesc->streams[1].candidates[0];
if (parse_hostname_to_addr(server,&ss,&ss_len)<0){
ms_error("Fail to parser stun server address: %s",server);
return -1;
@ -569,28 +565,25 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
}
}
}
if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0)
|| sock2==-1){
strcpy(call->localdesc->addr,ac->addr);
}
close_socket(sock1);
if (sock2!=-1) close_socket(sock2);
return ret;
}
return -1;
}
void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params){
if (lp_config_get_int(lc->config,"net","activate_edge_workarounds",0)==1){
ms_message("Stun server ping time is %i ms",ping_time_ms);
int threshold=lp_config_get_int(lc->config,"net","edge_ping_time",500);
if (ping_time_ms>threshold){
int edge_ptime=lp_config_get_int(lc->config,"net","edge_ptime",100);
int edge_bw=lp_config_get_int(lc->config,"net","edge_bw",30);
int edge_bw=lp_config_get_int(lc->config,"net","edge_bw",20);
/* we are in a 2G network*/
params->up_bw=params->down_bw=edge_bw;
params->up_ptime=params->down_ptime=edge_ptime;
params->has_video=FALSE;
}/*else use default settings */
}

View file

@ -240,7 +240,6 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
if (result->payloads && !only_telephone_event(result->payloads) && (remote_offer->rtp_port!=0 || remote_offer->rtp_port==SalStreamSendOnly)){
strcpy(result->rtp_addr,local_cap->rtp_addr);
strcpy(result->rtcp_addr,local_cap->rtcp_addr);
memcpy(result->candidates,local_cap->candidates,sizeof(result->candidates));
result->rtp_port=local_cap->rtp_port;
result->rtcp_port=local_cap->rtcp_port;
result->bandwidth=local_cap->bandwidth;

View file

@ -230,7 +230,13 @@ MSList *linphone_find_friend(MSList *fl, const LinphoneAddress *fri, LinphoneFri
void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc);
void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt);
int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call);
typedef struct StunCandidate{
char addr[64];
int port;
}StunCandidate;
int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call, StunCandidate *ac, StunCandidate *vc);
void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params);
int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call);
void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session);

View file

@ -105,11 +105,6 @@ typedef enum{
SalStreamInactive
}SalStreamDir;
typedef struct SalEndpointCandidate{
char addr[64];
int port;
}SalEndpointCandidate;
#define SAL_ENDPOINT_CANDIDATE_MAX 2
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_ADDR_LEN 64
@ -159,7 +154,6 @@ typedef struct SalStreamDescription{
MSList *payloads; //<list of PayloadType
int bandwidth;
int ptime;
SalEndpointCandidate candidates[SAL_ENDPOINT_CANDIDATE_MAX];
SalStreamDir dir;
SalSrtpCryptoAlgo crypto[SAL_CRYPTO_ALGO_MAX];
unsigned int crypto_local_tag;

View file

@ -279,10 +279,6 @@ static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription
rtcp_addr=desc->rtcp_addr;
rtp_port=desc->rtp_port;
rtcp_port=desc->rtcp_port;
if (desc->candidates[0].addr[0]!='\0'){
rtp_addr=desc->candidates[0].addr;
rtp_port=desc->candidates[0].port;
}
if (desc->proto == SalProtoRtpSavp) {
int i;

@ -1 +1 @@
Subproject commit beb4318d1e5eb282adc82967a9c80e89cd406045
Subproject commit 18a6f4d8629593125cc7b707f5fdad1462b2dcd9