From 15b915e036e163785adc3353580aa7925e83c4c9 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Mon, 23 Mar 2015 09:01:33 +0100 Subject: [PATCH] =?UTF-8?q?-No=20longer=20rewrite=20callparams->has=5Fvide?= =?UTF-8?q?o,=20but=20use=20dedicated=20params=20to=20save=20offers=20answ?= =?UTF-8?q?er=20result=20regarding=20video=20-Invoke=20FIR=20in=20method?= =?UTF-8?q?=20linphone=5Fcore=5Fsend=5Fvfu=5Frequest=20-Invoke=20CallStats?= =?UTF-8?q?Updated=20even=20in=20case=20of=20scheduled=20updates=20-Fix=20?= =?UTF-8?q?media=20direction=20in=20case=20of=20paused/resumed=20with=20pa?= =?UTF-8?q?used=20by=20=C2=AB=C2=A0inactive=C2=A0=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- coreapi/callbacks.c | 2 - coreapi/linphonecall.c | 73 +++++++++--- coreapi/linphonecore.c | 5 +- coreapi/linphonecore.h | 3 +- coreapi/private.h | 5 + tester/call_tester.c | 229 +++++++++++++++++++++++++++++++++++- tester/liblinphone_tester.h | 1 + tester/tester.c | 20 ++++ 8 files changed, 310 insertions(+), 28 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index d3ee638ce..4920f22bc 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -491,8 +491,6 @@ static void call_accepted(SalOp *op){ #endif //BUILD_UPNP md=sal_call_get_final_media_description(op); - if (md) /*make sure re-invite will not propose video again*/ - call->params->has_video &= linphone_core_media_description_contains_video_stream(md); switch (call->state){ case LinphoneCallOutgoingProgress: diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 5b550a245..8129b993d 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -647,7 +647,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * ms_warning("Cannot get audio local ssrc for call [%p]",call); nb_active_streams++; - if (call->params->has_video){ + if (call->params->has_video && (!call->params->internal_call_update || !call->current_params->video_declined)){ strncpy(md->streams[1].rtp_addr,linphone_call_get_public_ip_for_stream(call,1),sizeof(md->streams[1].rtp_addr)); strncpy(md->streams[1].rtcp_addr,linphone_call_get_public_ip_for_stream(call,1),sizeof(md->streams[1].rtcp_addr)); strncpy(md->streams[1].name,"Video",sizeof(md->streams[1].name)-1); @@ -670,6 +670,8 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * else ms_warning("Cannot get video local ssrc for call [%p]",call); nb_active_streams++; + } else { + ms_message("Don't put video stream on local offer for call [%p]",call); } if (md->nb_streams < nb_active_streams) @@ -973,7 +975,6 @@ static void linphone_call_incoming_select_ip_version(LinphoneCall *call){ */ void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, const SalMediaDescription *md) { int i; - call->params->has_video &= linphone_core_media_description_contains_video_stream(md); /* Handle AVPF, SRTP and DTLS. */ call->params->avpf_enabled = sal_media_description_has_avpf(md); @@ -1171,8 +1172,11 @@ static void linphone_call_set_terminated(LinphoneCall *call){ } void linphone_call_fix_call_parameters(LinphoneCall *call){ - call->params->has_video=call->current_params->has_video; - + if (sal_call_is_offerer(call->op)) { + /*get remote params*/ + const LinphoneCallParams* lcp = linphone_call_get_remote_params(call); + call->current_params->video_declined = call->params->has_video && !lcp->has_video; + } switch(call->params->media_encryption) { case LinphoneMediaEncryptionZRTP: case LinphoneMediaEncryptionDTLS: @@ -1669,7 +1673,11 @@ void linphone_call_enable_camera (LinphoneCall *call, bool_t enable){ **/ void linphone_call_send_vfu_request(LinphoneCall *call) { #ifdef VIDEO_ENABLED - if (call->core->sip_conf.vfu_with_info) { + 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) { + 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) { if (LinphoneCallStreamsRunning == linphone_call_get_state(call)) sal_call_send_vfu_request(call->op); } else { @@ -3313,6 +3321,17 @@ static void report_bandwidth(LinphoneCall *call, MediaStream *as, MediaStream *v call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_upload_bandwidth=(as_active) ? (media_stream_get_rtcp_up_bw(as)*1e-3) : 0; call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_download_bandwidth=(vs_active) ? (media_stream_get_rtcp_down_bw(vs)*1e-3) : 0; call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_upload_bandwidth=(vs_active) ? (media_stream_get_rtcp_up_bw(vs)*1e-3) : 0; + if (as_active) { + call->stats[LINPHONE_CALL_STATS_AUDIO].updated|=LINPHONE_CALL_STATS_PERIODICAL_UPDATE; + linphone_core_notify_call_stats_updated(call->core, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]); + call->stats[LINPHONE_CALL_STATS_AUDIO].updated=0; + } + if (vs_active) { + call->stats[LINPHONE_CALL_STATS_VIDEO].updated|=LINPHONE_CALL_STATS_PERIODICAL_UPDATE; + linphone_core_notify_call_stats_updated(call->core, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]); + call->stats[LINPHONE_CALL_STATS_VIDEO].updated=0; + + } ms_message( "Bandwidth usage for call [%p]:\n" "\tRTP audio=[d=%5.1f,u=%5.1f], video=[d=%5.1f,u=%5.1f] kbits/sec\n" @@ -3327,6 +3346,7 @@ static void report_bandwidth(LinphoneCall *call, MediaStream *as, MediaStream *v call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_download_bandwidth, call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_upload_bandwidth ); + } static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){ @@ -3394,6 +3414,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ ice_session_select_candidates(call->ice_session); if (ice_session_role(call->ice_session) == IR_Controlling && lp_config_get_int(call->core->config, "sip", "update_call_when_ice_completed", TRUE)) { + params->internal_call_update = TRUE; linphone_core_update_call(call->core, call, params); } change_ice_media_destinations(call); @@ -3404,6 +3425,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ ice_session_select_candidates(call->ice_session); if (ice_session_role(call->ice_session) == IR_Controlling) { /* At least one ICE session has succeeded, so perform a call update. */ + params->internal_call_update = TRUE; linphone_core_update_call(call->core, call, params); } } @@ -3499,7 +3521,13 @@ void linphone_call_notify_stats_updated(LinphoneCall *call, int stream_index){ LinphoneCallStats *stats=&call->stats[stream_index]; LinphoneCore *lc=call->core; if (stats->updated){ - linphone_reporting_on_rtcp_update(call, stream_index); + switch(stats->updated) { + case LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE: + case LINPHONE_CALL_STATS_SENT_RTCP_UPDATE: + linphone_reporting_on_rtcp_update(call, stream_index); + break; + default:break; + } linphone_core_notify_call_stats_updated(lc, call, stats); stats->updated = 0; } @@ -3563,18 +3591,29 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse int disconnect_timeout = linphone_core_get_nortp_timeout(call->core); bool_t disconnected=FALSE; - if ((call->state==LinphoneCallStreamsRunning || call->state==LinphoneCallOutgoingEarlyMedia || call->state==LinphoneCallIncomingEarlyMedia) && one_second_elapsed){ - float audio_load=0, video_load=0; - if (call->audiostream!=NULL){ - if (call->audiostream->ms.sessions.ticker) - audio_load=ms_ticker_get_average_load(call->audiostream->ms.sessions.ticker); + switch (call->state) { + case LinphoneCallStreamsRunning: + case LinphoneCallOutgoingEarlyMedia: + case LinphoneCallIncomingEarlyMedia: + case LinphoneCallPausedByRemote: + case LinphoneCallPaused: + if (one_second_elapsed){ + float audio_load=0, video_load=0; + if (call->audiostream!=NULL){ + if (call->audiostream->ms.sessions.ticker) + audio_load=ms_ticker_get_average_load(call->audiostream->ms.sessions.ticker); + } + if (call->videostream!=NULL){ + if (call->videostream->ms.sessions.ticker) + video_load=ms_ticker_get_average_load(call->videostream->ms.sessions.ticker); + } + report_bandwidth(call,(MediaStream*)call->audiostream,(MediaStream*)call->videostream); + ms_message("Thread processing load: audio=%f\tvideo=%f",audio_load,video_load); } - if (call->videostream!=NULL){ - if (call->videostream->ms.sessions.ticker) - video_load=ms_ticker_get_average_load(call->videostream->ms.sessions.ticker); - } - report_bandwidth(call,(MediaStream*)call->audiostream,(MediaStream*)call->videostream); - ms_message("Thread processing load: audio=%f\tvideo=%f",audio_load,video_load); + break; + default: + /*no stats for other states*/ + break; } #ifdef BUILD_UPNP diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 6b08cc610..9af0c79ee 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3643,7 +3643,6 @@ int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, cons ms_warning("Video isn't supported in conference"); call->params->has_video = FALSE; } - call->params->has_video &= linphone_core_media_description_contains_video_stream(remote_desc); 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) @@ -6890,9 +6889,7 @@ const char *linphone_media_encryption_to_string(LinphoneMediaEncryption menc){ return "INVALID"; } -/** - * Returns whether a media encryption scheme is supported by the LinphoneCore engine -**/ + bool_t linphone_core_media_encryption_supported(const LinphoneCore *lc, LinphoneMediaEncryption menc){ switch(menc){ case LinphoneMediaEncryptionSRTP: diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index c79d9a053..761bdcd63 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -513,6 +513,7 @@ typedef enum _LinphoneUpnpState LinphoneUpnpState; #define LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE (1 << 0) /**< received_rtcp field of LinphoneCallStats object has been updated */ #define LINPHONE_CALL_STATS_SENT_RTCP_UPDATE (1 << 1) /**< sent_rtcp field of LinphoneCallStats object has been updated */ +#define LINPHONE_CALL_STATS_PERIODICAL_UPDATE (1 << 2) /**< Every seconds LinphoneCallStats object has been updated */ /** @@ -529,7 +530,7 @@ typedef struct _LinphoneCallStats LinphoneCallStats; * The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. * * To receive these informations periodically and as soon as they are computed, the application is invited to place a #LinphoneCoreCallStatsUpdatedCb callback in the LinphoneCoreVTable structure - * it passes for instanciating the LinphoneCore object (see linphone_core_new() ). + * it passes for instantiating the LinphoneCore object (see linphone_core_new() ). * * At any time, the application can access last computed statistics using linphone_call_get_audio_stats() or linphone_call_get_video_stats(). **/ diff --git a/coreapi/private.h b/coreapi/private.h index 4dea61ebb..601928929 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -110,6 +110,8 @@ struct _LinphoneCallParams{ LinphonePrivacyMask privacy; LinphoneMediaDirection audio_dir; 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)*/ }; @@ -438,6 +440,9 @@ void linphone_core_stop_waiting(LinphoneCore *lc); int linphone_core_proceed_with_invite_if_ready(LinphoneCore *lc, LinphoneCall *call, LinphoneProxyConfig *dest_proxy); int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, const LinphoneAddress* destination/* = NULL if to be taken from the call log */); int linphone_core_restart_invite(LinphoneCore *lc, LinphoneCall *call); +/* + * param automatic_offering aims is to take into account previous answer for video in case of automatic re-invite. + * Purpose is to avoid to re-ask video previously declined */ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call); int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState next_state, const char *state_info); void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call); diff --git a/tester/call_tester.c b/tester/call_tester.c index 710696216..bebdf68ab 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -84,6 +84,7 @@ void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState void call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *lstats) { stats* counters = get_stats(lc); + counters->number_of_LinphoneCallStatsUpdated++; if (lstats->updated == LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) { counters->number_of_rtcp_received++; } else if (lstats->updated == LINPHONE_CALL_STATS_SENT_RTCP_UPDATE) { @@ -1614,7 +1615,7 @@ static void call_with_declined_video_using_policy(void) { call_with_declined_video_base(TRUE); } -static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t using_policy,LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) { +static 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) { LinphoneCallTestParams caller_test_params = {0}, callee_test_params = {0}; LinphoneCall* marie_call; LinphoneCall* pauline_call; @@ -1689,12 +1690,15 @@ static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* ma liblinphone_tester_check_rtcp(marie,pauline); - linphone_core_terminate_all_calls(pauline->lc); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); } } +static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t using_policy,LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) { + video_call_base_2(pauline,marie,using_policy,mode,callee_video_enabled,caller_video_enabled); + linphone_core_terminate_all_calls(pauline->lc); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); +} static void video_call(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); @@ -2838,6 +2842,139 @@ static void multiple_early_media(void) { linphone_core_manager_destroy(marie2); linphone_core_manager_destroy(pauline); } + +static void check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, LinphoneCoreManager* mgr2,LinphoneMediaDirection audio_dir, LinphoneMediaDirection video_dir) { + CU_ASSERT_PTR_NOT_NULL(call); + if (call) { + int current_recv_iframe = mgr->stat.number_of_IframeDecoded; + int expected_recv_iframe=0; + int dummy = 0; + const LinphoneCallParams *params = linphone_call_get_current_params(call); + CU_ASSERT_EQUAL(audio_dir,linphone_call_params_get_audio_direction(params)); + CU_ASSERT_EQUAL(video_dir,linphone_call_params_get_video_direction(params)); + + linphone_call_set_next_video_frame_decoded_callback(call,linphone_call_cb,mgr->lc); + linphone_call_send_vfu_request(call); + + wait_for_until(mgr->lc,mgr2->lc,&dummy,1,2000); + + switch (video_dir) { + case LinphoneMediaDirectionInactive: + CU_ASSERT_TRUE(linphone_call_get_video_stats(call)->upload_bandwidth<5); + case LinphoneMediaDirectionSendOnly: + expected_recv_iframe = 0; + CU_ASSERT_TRUE(linphone_call_get_video_stats(call)->download_bandwidth<5); + break; + case LinphoneMediaDirectionRecvOnly: + CU_ASSERT_TRUE(linphone_call_get_video_stats(call)->upload_bandwidth<5); + case LinphoneMediaDirectionSendRecv: + expected_recv_iframe = 1; + break; + } + + CU_ASSERT_TRUE(wait_for_until(mgr->lc,mgr2->lc, &mgr->stat.number_of_IframeDecoded,current_recv_iframe + expected_recv_iframe,3000)); + + switch (audio_dir) { + case LinphoneMediaDirectionInactive: + CU_ASSERT_TRUE(linphone_call_get_audio_stats(call)->upload_bandwidth<5); + case LinphoneMediaDirectionSendOnly: + CU_ASSERT_TRUE(linphone_call_get_video_stats(call)->download_bandwidth<5); + if (audio_dir == LinphoneMediaDirectionSendOnly) CU_ASSERT_TRUE(linphone_call_get_audio_stats(call)->upload_bandwidth>70); + break; + case LinphoneMediaDirectionRecvOnly: + CU_ASSERT_TRUE(linphone_call_get_audio_stats(call)->upload_bandwidth<5); + case LinphoneMediaDirectionSendRecv: + CU_ASSERT_TRUE(linphone_call_get_audio_stats(call)->download_bandwidth>70); + if (audio_dir == LinphoneMediaDirectionSendRecv) CU_ASSERT_TRUE(linphone_call_get_audio_stats(call)->upload_bandwidth>70); + break; + } + } + +} +#if 0 +static void accept_call_in_send_only(void) { + LinphoneCoreManager* pauline, *marie; + LinphoneCallParams *params; + LinphoneVideoPolicy pol; + LinphoneCall *call; + int begin; + int leaked_objects; + + belle_sip_object_enable_leak_detector(TRUE); + begin=belle_sip_object_get_object_count(); + + pauline = linphone_core_manager_new("pauline_rc"); + marie = linphone_core_manager_new("marie_rc"); + + pol.automatically_accept=1; + pol.automatically_initiate=1; + + linphone_core_enable_video(pauline->lc,TRUE,TRUE); + linphone_core_set_video_policy(pauline->lc,&pol); + linphone_core_set_video_device(pauline->lc,"Mire: Mire (synthetic moving picture)"); + + linphone_core_enable_video(marie->lc,TRUE,TRUE); + linphone_core_set_video_policy(marie->lc,&pol); + linphone_core_set_video_device(marie->lc,"Mire: Mire (synthetic moving picture)"); + + linphone_call_set_next_video_frame_decoded_callback(linphone_core_invite_address(pauline->lc,marie->identity) + ,linphone_call_cb + ,pauline->lc); + + + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc, &marie->stat.number_of_LinphoneCallIncomingReceived,1)); + call=linphone_core_get_current_call(marie->lc); + if (call) { + params=linphone_core_create_default_call_parameters(marie->lc); + linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendOnly); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionSendOnly); + linphone_core_accept_call_with_params(marie->lc,call,params); + linphone_call_params_destroy(params); + + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc, &marie->stat.number_of_LinphoneCallStreamsRunning,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc, &pauline->stat.number_of_LinphoneCallPausedByRemote,1)); + + { + const LinphoneCallParams *params = linphone_call_get_current_params(call); + CU_ASSERT_EQUAL(LinphoneMediaDirectionSendOnly,linphone_call_params_get_audio_direction(params)); + CU_ASSERT_EQUAL(LinphoneMediaDirectionSendOnly,linphone_call_params_get_video_direction(params)); + + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc, &marie->stat.number_of_LinphoneCallStatsUpdated,2)); + CU_ASSERT_TRUE(linphone_call_get_audio_stats(call)->download_bandwidth<5); + CU_ASSERT_TRUE(linphone_call_get_video_stats(call)->download_bandwidth<5); + } + } + + + call=linphone_core_get_current_call(pauline->lc); + if (call) { + const LinphoneCallParams *params = linphone_call_get_current_params(call); + CU_ASSERT_EQUAL(LinphoneMediaDirectionRecvOnly,linphone_call_params_get_audio_direction(params)); + CU_ASSERT_EQUAL(LinphoneMediaDirectionRecvOnly,linphone_call_params_get_video_direction(params)); + + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc, &pauline->stat.number_of_IframeDecoded,1)); + + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc, &pauline->stat.number_of_LinphoneCallStatsUpdated,4)); + + CU_ASSERT_TRUE(linphone_call_get_audio_stats(call)->download_bandwidth>0); + CU_ASSERT_TRUE(linphone_call_get_video_stats(call)->download_bandwidth>0); + + CU_ASSERT_TRUE(linphone_call_get_audio_stats(call)->upload_bandwidth<5); + CU_ASSERT_TRUE(linphone_call_get_video_stats(call)->upload_bandwidth<5); + } + + end_call(marie,pauline); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + leaked_objects=belle_sip_object_get_object_count()-begin; + + CU_ASSERT_TRUE(leaked_objects==0); + if (leaked_objects>0){ + belle_sip_object_dump_active_objects(); + } + +} +#endif /*0*/ #endif static char *create_filepath(const char *dir, const char *filename, const char *ext) { @@ -3501,6 +3638,84 @@ static void call_with_transport_change_after_released(void) { static void unsucessfull_call_with_transport_change_after_released(void) { call_with_transport_change_base(FALSE); } +#ifdef VIDEO_ENABLED + +static void video_call_with_re_invite_inactive_followed_by_re_invite_base(bool_t no_sdp) { + int begin; + int leaked_objects; + LinphoneCoreManager* marie; + LinphoneCoreManager* pauline; + LinphoneCallParams *params; + + belle_sip_object_enable_leak_detector(TRUE); + begin=belle_sip_object_get_object_count(); + + marie = linphone_core_manager_new( "marie_rc"); + pauline = linphone_core_manager_new( "pauline_rc"); + linphone_core_set_avpf_mode(pauline->lc,TRUE); + linphone_core_set_video_device(pauline->lc,"Mire: Mire (synthetic moving picture)"); + linphone_core_set_video_device(marie->lc,"Mire: Mire (synthetic moving picture)"); + linphone_core_set_avpf_mode(marie->lc,TRUE); + + video_call_base_2(marie,pauline,TRUE,LinphoneMediaEncryptionNone,TRUE,TRUE); + + if (linphone_core_get_current_call(marie->lc)) { + params=linphone_core_create_call_params(marie->lc,linphone_core_get_current_call(marie->lc)); + linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionInactive); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionInactive); + + linphone_core_update_call(marie->lc, linphone_core_get_current_call(marie->lc),params); + linphone_call_params_destroy(params); + + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallUpdating,1)); + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallPaused,1)); + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallPausedByRemote,1)); + + check_media_direction(marie,linphone_core_get_current_call(marie->lc),pauline,LinphoneMediaDirectionInactive,LinphoneMediaDirectionInactive); + check_media_direction(pauline,linphone_core_get_current_call(pauline->lc), marie, LinphoneMediaDirectionInactive,LinphoneMediaDirectionInactive); + + if (no_sdp) { + linphone_core_enable_sdp_200_ack(marie->lc,TRUE); + } + + /* + currently update call cannot be used in paused state, might not be good. + params=linphone_core_create_call_params(marie->lc,linphone_core_get_current_call(marie->lc)); + linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendRecv); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionSendRecv); + linphone_core_update_call(marie->lc,linphone_core_get_current_call(marie->lc),params); + linphone_call_params_destroy(params); + */ + + linphone_core_resume_call(marie->lc,linphone_core_get_current_call(marie->lc)); + + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallResuming,1)); + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + + check_media_direction(marie,linphone_core_get_current_call(marie->lc),pauline,LinphoneMediaDirectionSendRecv,LinphoneMediaDirectionSendRecv); + check_media_direction(pauline,linphone_core_get_current_call(pauline->lc),marie,LinphoneMediaDirectionSendRecv,LinphoneMediaDirectionSendRecv); + + } + end_call(marie,pauline); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + + leaked_objects=belle_sip_object_get_object_count()-begin; + CU_ASSERT_TRUE(leaked_objects==0); + if (leaked_objects>0){ + belle_sip_object_dump_active_objects(); + } +} + +static void video_call_with_re_invite_inactive_followed_by_re_invite() { + video_call_with_re_invite_inactive_followed_by_re_invite_base(FALSE); +} + +static void video_call_with_re_invite_inactive_followed_by_re_invite_no_sdp() { + video_call_with_re_invite_inactive_followed_by_re_invite_base(TRUE); +} +#endif test_t call_tests[] = { { "Phone number normalization", phone_number_normalization }, @@ -3567,6 +3782,11 @@ test_t call_tests[] = { { "DTLS SRTP ice video call",dtls_srtp_ice_video_call}, { "DTLS SRTP ice video call with relay",dtls_srtp_ice_video_call_with_relay}, { "Video call with limited bandwidth", video_call_limited_bandwidth}, +#if 0 + { "Video call accepted in send only", accept_call_in_send_only}, +#endif /*0*/ + { "Video call with re-invite(inactive) followed by re-invite", video_call_with_re_invite_inactive_followed_by_re_invite}, + { "Video call with re-invite(inactive) followed by re-invite(no sdp)", video_call_with_re_invite_inactive_followed_by_re_invite_no_sdp}, #endif { "SRTP ice call", srtp_ice_call }, { "ZRTP ice call", zrtp_ice_call }, @@ -3606,6 +3826,7 @@ test_t call_tests[] = { { "Call with generic CN", call_with_generic_cn }, { "Call with transport change after released", call_with_transport_change_after_released }, { "Unsuccessful call with transport change after released",unsucessfull_call_with_transport_change_after_released} + }; test_suite_t call_test_suite = { diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 1c9ff34b4..b77d1debc 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -202,6 +202,7 @@ typedef struct _stats { char * dtmf_list_received; int dtmf_count; + int number_of_LinphoneCallStatsUpdated; int number_of_rtcp_sent; int number_of_rtcp_received; diff --git a/tester/tester.c b/tester/tester.c index f63562f71..daec6509f 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -259,6 +259,26 @@ LinphoneCoreManager* linphone_core_manager_init(const char* rc_file) { linphone_core_set_ringback(mgr->lc, NULL); #endif +#ifdef VIDEO_ENABLED + { + MSWebCam *cam; + +#ifdef _MSC_VER + extern __declspec(dllimport) MSWebCamDesc mire_desc; +#else + extern MSWebCamDesc mire_desc; +#endif + + cam = ms_web_cam_manager_get_cam(ms_web_cam_manager_get(), "Mire: Mire (synthetic moving picture)"); + + if (cam == NULL) { + cam=ms_web_cam_new(&mire_desc); + ms_web_cam_manager_add_cam(ms_web_cam_manager_get(),cam); + } + } +#endif + + if( manager_count >= 2){ char hellopath[512]; char *recordpath = ms_strdup_printf("%s/record_for_lc_%p.wav",bc_tester_writable_dir_prefix,mgr->lc);