Commit f83d50db authored by Sandrine Avakian's avatar Sandrine Avakian
Browse files

Fixing bugs on implicit RTCP feedback:

-AVP implicit to AVP implicit calls now using RTCP feedback packets.
-Fixing bugs in call_tester.c
parent 832a1c4b
/*
linphone
Copyright (C) 2012 Belledonne Communications, Grenoble, France
......@@ -629,14 +630,15 @@ static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb
payload_type_set_avpf_params(pt, avpf_params);
}
static void sdp_parse_rtcp_fb_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
static bool_t sdp_parse_rtcp_fb_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
belle_sip_list_t *it;
belle_sdp_attribute_t *attribute;
belle_sdp_rtcp_fb_attribute_t *fb_attribute;
MSList *pt_it;
PayloadType *pt;
int8_t pt_num;
bool_t retval = FALSE;
/* Handle rtcp-fb attributes that concern all payload types. */
for (it = belle_sdp_media_description_get_attributes(media_desc); it != NULL; it = it->next) {
attribute = BELLE_SDP_ATTRIBUTE(it->data);
......@@ -646,6 +648,7 @@ static void sdp_parse_rtcp_fb_parameters(belle_sdp_media_description_t *media_de
for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) {
pt = (PayloadType *)pt_it->data;
apply_rtcp_fb_attribute_to_payload(fb_attribute, stream, pt);
retval = TRUE;
}
}
}
......@@ -659,12 +662,14 @@ static void sdp_parse_rtcp_fb_parameters(belle_sdp_media_description_t *media_de
pt_num = belle_sdp_rtcp_fb_attribute_get_id(fb_attribute);
for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) {
pt = (PayloadType *)pt_it->data;
retval = TRUE;
if (payload_type_get_number(pt) == (int)pt_num) {
apply_rtcp_fb_attribute_to_payload(fb_attribute, stream, pt);
}
}
}
}
return retval;
}
static void sal_init_rtcp_xr_description(OrtpRtcpXrConfiguration *config) {
......@@ -727,6 +732,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
belle_sip_list_t *custom_attribute_it;
const char* value;
const char *mtype,*proto;
bool_t has_avpf_attributes;
stream=&md->streams[md->nb_streams];
media=belle_sdp_media_description_get_media ( media_desc );
......@@ -830,12 +836,17 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
/* Get ICE candidate attributes if any */
sdp_parse_media_ice_parameters(media_desc, stream);
has_avpf_attributes = sdp_parse_rtcp_fb_parameters(media_desc, stream);
/* Get RTCP-FB attributes if any */
if (sal_stream_description_has_avpf(stream) || sal_stream_description_has_implicit_avpf(stream)) {
if (sal_stream_description_has_avpf(stream)) {
enable_avpf_for_stream(stream);
sdp_parse_rtcp_fb_parameters(media_desc, stream);
}
else if (has_avpf_attributes ){
stream->implicit_rtcp_fb = TRUE;
}
/* Get RTCP-XR attributes if any */
stream->rtcp_xr = md->rtcp_xr; // Use session parameters if no stream parameters are defined
......
......@@ -1452,6 +1452,7 @@ void linphone_call_fix_call_parameters(LinphoneCall *call, SalMediaDescription *
if (rmd) {
linphone_call_compute_streams_indexes(call, rmd);
linphone_call_update_biggest_desc(call, rmd);
call->params->implicit_rtcp_fb &= sal_media_description_has_implicit_avpf(rmd);
}
rcp = linphone_call_get_remote_params(call);
if (rcp){
......@@ -1767,9 +1768,8 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){
break;
case LinphoneMediaEncryptionNone:
call->current_params->media_encryption=LinphoneMediaEncryptionNone;
break;
break;
}
call->current_params->avpf_enabled = linphone_call_all_streams_avpf_enabled(call) && sal_media_description_has_avpf(md);
if (call->current_params->avpf_enabled == TRUE) {
call->current_params->avpf_rr_interval = linphone_call_get_avpf_rr_interval(call);
......@@ -1780,6 +1780,7 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){
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;
......@@ -1788,6 +1789,7 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){
call->current_params->audio_multicast_enabled = FALSE;
sd=sal_media_description_find_best_stream(md,SalVideo);
call->current_params->implicit_rtcp_fb = sd ? sal_stream_description_has_implicit_avpf(sd): FALSE;
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;
......@@ -1795,7 +1797,8 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){
} else
call->current_params->video_multicast_enabled = FALSE;
sd=sal_media_description_find_best_stream(md,SalText);
}
return call->current_params;
......@@ -2043,10 +2046,11 @@ void linphone_call_enable_camera (LinphoneCall *call, bool_t enable){
void linphone_call_send_vfu_request(LinphoneCall *call) {
#ifdef VIDEO_ENABLED
const LinphoneCallParams *current_params = linphone_call_get_current_params(call);
if (current_params->avpf_enabled && call->videostream && media_stream_get_state((const MediaStream *)call->videostream) == MSStreamStarted) {
if ((current_params->avpf_enabled || current_params->implicit_rtcp_fb )&& call->videostream && media_stream_get_state((const MediaStream *)call->videostream) == MSStreamStarted) { // || sal_media_description_has_implicit_avpf((const SalMediaDescription *)call->resultdesc)
ms_message("Request Full Intra Request on call [%p]", call);
video_stream_send_fir(call->videostream);
} else if (call->core->sip_conf.vfu_with_info) {
ms_message("Request SIP INFO FIR on call [%p]", call);
if (LinphoneCallStreamsRunning == linphone_call_get_state(call))
sal_call_send_vfu_request(call->op);
} else {
......
......@@ -434,6 +434,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
result->dtls_role = SalDtlsRoleInvalid;
}
result->rtcp_mux = remote_answer->rtcp_mux && local_offer->rtcp_mux;
result->implicit_rtcp_fb = local_offer->implicit_rtcp_fb && remote_answer->implicit_rtcp_fb;
}
......@@ -502,6 +503,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
result->dtls_role = SalDtlsRoleInvalid;
}
result->rtcp_mux = remote_offer->rtcp_mux && local_cap->rtcp_mux;
result->implicit_rtcp_fb = local_cap->implicit_rtcp_fb && remote_offer->implicit_rtcp_fb;
}
......
......@@ -61,7 +61,6 @@ SalMediaDescription *sal_media_description_new(){
md->streams[i].dir=SalStreamInactive;
md->streams[i].rtp_port = 0;
md->streams[i].rtcp_port = 0;
md->streams[i].implicit_rtcp_fb = TRUE;
}
return md;
}
......@@ -267,6 +266,16 @@ bool_t sal_media_description_has_avpf(const SalMediaDescription *md) {
return TRUE;
}
bool_t sal_media_description_has_implicit_avpf(const SalMediaDescription *md) {
int i;
if (md->nb_streams == 0) return FALSE;
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
if (!sal_stream_description_active(&md->streams[i])) continue;
if (sal_stream_description_has_implicit_avpf(&md->streams[i]) != TRUE) return FALSE;
}
return TRUE;
}
bool_t sal_media_description_has_srtp(const SalMediaDescription *md) {
int i;
if (md->nb_streams == 0) return FALSE;
......
......@@ -318,6 +318,7 @@ bool_t sal_stream_description_has_implicit_avpf(const SalStreamDescription *sd);
bool_t sal_stream_description_has_srtp(const SalStreamDescription *sd);
bool_t sal_stream_description_has_dtls(const SalStreamDescription *sd);
bool_t sal_media_description_has_avpf(const SalMediaDescription *md);
bool_t sal_media_description_has_implicit_avpf(const SalMediaDescription *md);
bool_t sal_media_description_has_srtp(const SalMediaDescription *md);
bool_t sal_media_description_has_dtls(const SalMediaDescription *md);
int sal_media_description_get_nb_active_streams(const SalMediaDescription *md);
......
......@@ -1966,68 +1966,68 @@ static void call_with_declined_video_using_policy(void) {
}
void video_call_base_2(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t using_policy,LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) {
void video_call_base_2(LinphoneCoreManager* caller,LinphoneCoreManager* callee, bool_t using_policy,LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) {
LinphoneCallTestParams caller_test_params = {0}, callee_test_params = {0};
LinphoneCall* marie_call;
LinphoneCall* pauline_call;
LinphoneVideoPolicy marie_policy, pauline_policy;
LinphoneCall* callee_call;
LinphoneCall* caller_call;
LinphoneVideoPolicy callee_policy, caller_policy;
if (using_policy) {
marie_policy.automatically_initiate=FALSE;
marie_policy.automatically_accept=TRUE;
pauline_policy.automatically_initiate=TRUE;
pauline_policy.automatically_accept=FALSE;
callee_policy.automatically_initiate=FALSE;
callee_policy.automatically_accept=TRUE;
caller_policy.automatically_initiate=TRUE;
caller_policy.automatically_accept=FALSE;
linphone_core_set_video_policy(marie->lc,&marie_policy);
linphone_core_set_video_policy(pauline->lc,&pauline_policy);
linphone_core_set_video_policy(callee->lc,&callee_policy);
linphone_core_set_video_policy(caller->lc,&caller_policy);
}
linphone_core_enable_video_display(marie->lc, callee_video_enabled);
linphone_core_enable_video_capture(marie->lc, callee_video_enabled);
linphone_core_enable_video_display(callee->lc, callee_video_enabled);
linphone_core_enable_video_capture(callee->lc, callee_video_enabled);
linphone_core_enable_video_display(pauline->lc, caller_video_enabled);
linphone_core_enable_video_capture(pauline->lc, caller_video_enabled);
linphone_core_enable_video_display(caller->lc, caller_video_enabled);
linphone_core_enable_video_capture(caller->lc, caller_video_enabled);
if (mode==LinphoneMediaEncryptionDTLS) { /* for DTLS we must access certificates or at least have a directory to store them */
marie->lc->user_certificates_path = bc_tester_file("certificates-marie");
pauline->lc->user_certificates_path = bc_tester_file("certificates-pauline");
belle_sip_mkdir(marie->lc->user_certificates_path);
belle_sip_mkdir(pauline->lc->user_certificates_path);
callee->lc->user_certificates_path = bc_tester_file("certificates-marie");
caller->lc->user_certificates_path = bc_tester_file("certificates-pauline");
belle_sip_mkdir(callee->lc->user_certificates_path);
belle_sip_mkdir(caller->lc->user_certificates_path);
}
linphone_core_set_media_encryption(marie->lc,mode);
linphone_core_set_media_encryption(pauline->lc,mode);
linphone_core_set_media_encryption(callee->lc,mode);
linphone_core_set_media_encryption(caller->lc,mode);
caller_test_params.base=linphone_core_create_call_params(pauline->lc, NULL);
caller_test_params.base=linphone_core_create_call_params(caller->lc, NULL);
if (!using_policy)
linphone_call_params_enable_video(caller_test_params.base,TRUE);
if (!using_policy){
callee_test_params.base=linphone_core_create_call_params(marie->lc, NULL);
callee_test_params.base=linphone_core_create_call_params(callee->lc, NULL);
linphone_call_params_enable_video(callee_test_params.base,TRUE);
}
BC_ASSERT_TRUE(call_with_params2(pauline,marie,&caller_test_params,&callee_test_params,using_policy));
marie_call=linphone_core_get_current_call(marie->lc);
pauline_call=linphone_core_get_current_call(pauline->lc);
BC_ASSERT_TRUE(call_with_params2(caller,callee,&caller_test_params,&callee_test_params,using_policy));
callee_call=linphone_core_get_current_call(callee->lc);
caller_call=linphone_core_get_current_call(caller->lc);
linphone_call_params_destroy(caller_test_params.base);
if (callee_test_params.base) linphone_call_params_destroy(callee_test_params.base);
if (marie_call && pauline_call ) {
if (callee_call && caller_call ) {
if (callee_video_enabled && caller_video_enabled) {
BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call)));
BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(pauline_call)));
BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(callee_call)));
BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(caller_call)));
/*check video path*/
linphone_call_set_next_video_frame_decoded_callback(marie_call,linphone_call_iframe_decoded_cb,marie->lc);
linphone_call_send_vfu_request(marie_call);
BC_ASSERT_TRUE( wait_for(marie->lc,pauline->lc,&marie->stat.number_of_IframeDecoded,1));
linphone_call_set_next_video_frame_decoded_callback(callee_call,linphone_call_iframe_decoded_cb,callee->lc);
linphone_call_send_vfu_request(callee_call);
BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_IframeDecoded,1));
} else {
BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call)));
BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(pauline_call)));
BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(callee_call)));
BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(caller_call)));
}
liblinphone_tester_check_rtcp(marie,pauline);
liblinphone_tester_check_rtcp(callee,caller);
}
}
......@@ -2107,7 +2107,6 @@ void video_call_base_3(LinphoneCoreManager* caller,LinphoneCoreManager* callee,
linphone_core_set_media_encryption(caller->lc,mode);
/* Create call params */
caller_test_params.base=linphone_core_create_call_params(caller->lc, NULL);
if (!using_policy)
linphone_call_params_enable_video(caller_test_params.base,TRUE);
......@@ -2161,7 +2160,7 @@ static void video_call_disable_implicit_AVPF_on_callee(void) {
callee_lp = linphone_core_get_config(callee->lc);
lp_config_set_int(callee_lp,"rtp","rtcp_fb_implicit_rtcp_fb",0);
video_call_base_3(caller,callee,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE);
video_call_base_3(caller,callee,TRUE,LinphoneMediaEncryptionNone,TRUE,TRUE);
params = linphone_call_get_current_params(linphone_core_get_current_call(callee->lc));
BC_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), "RTP/AVP");
params2 =linphone_call_get_current_params(linphone_core_get_current_call(caller->lc));
......@@ -2182,7 +2181,7 @@ static void video_call_disable_implicit_AVPF_on_caller(void) {
caller_lp = linphone_core_get_config(caller->lc);
lp_config_set_int(caller_lp,"rtp","rtcp_fb_implicit_rtcp_fb",0);
video_call_base_3(caller,callee,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE);
video_call_base_3(caller,callee,TRUE,LinphoneMediaEncryptionNone,TRUE,TRUE);
params = linphone_call_get_current_params(linphone_core_get_current_call(callee->lc));
BC_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), "RTP/AVP");
params2 =linphone_call_get_current_params(linphone_core_get_current_call(caller->lc));
......@@ -2221,12 +2220,21 @@ static void video_call_implicit_AVPF_to_AVPF(void)
}
static void video_call_using_policy_AVPF_implicit_caller_and_callee(void) {
LinphoneCoreManager* callee = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* caller = linphone_core_manager_new(transport_supported(LinphoneTransportTcp) ? "pauline_rc" : "pauline_tcp_rc");
video_call_base_3(caller,callee,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE);
end_call(caller, callee);
linphone_core_manager_destroy(callee);
linphone_core_manager_destroy(caller);
}
static void video_call_base_avpf(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t using_policy,LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) {
linphone_core_set_avpf_mode(pauline->lc,LinphoneAVPFEnabled);
linphone_core_set_avpf_mode(marie->lc,LinphoneAVPFEnabled);
video_call_base_3(pauline,marie,using_policy,mode,callee_video_enabled,caller_video_enabled);
end_call(pauline, marie);
}
static void video_call_avpf(void) {
LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc");
LinphoneCoreManager* marie = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "marie_rc" : "marie_tcp_rc");
......@@ -2260,6 +2268,8 @@ static void video_call_dtls(void) {
}
static void video_call_using_policy(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTcp) ? "pauline_rc" : "pauline_tcp_rc");
......@@ -5774,6 +5784,7 @@ test_t call_tests[] = {
{ "Audio call with ICE no matching audio codecs", audio_call_with_ice_no_matching_audio_codecs },
#ifdef VIDEO_ENABLED
{ "Simple video call AVPF",video_call_avpf},
{ "Simple video call implicit AVPF both", video_call_using_policy_AVPF_implicit_caller_and_callee},
{ "Simple video call disable implicit AVPF on callee",video_call_disable_implicit_AVPF_on_callee},
{ "Simple video call disable implicit AVPF on caller",video_call_disable_implicit_AVPF_on_caller},
{ "Simple video call AVPF to implicit AVPF",video_call_AVPF_to_implicit_AVPF},
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment