summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2013-02-13 07:43:32 +0000
committerNanang Izzuddin <nanang@teluu.com>2013-02-13 07:43:32 +0000
commitc0eaf417c356756c1dee311fdad96c284ec08941 (patch)
tree0643c16211f00e4010225b3e78ac030895e6e3e7
parent01444a756c3eb047e4c44070dae49aed0359e607 (diff)
Re #1568: (PJSIP 2.x) No need to restart media when remote RTP address changed but ICE transport is running.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4345 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia/transport.h25
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c52
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c71
3 files changed, 90 insertions, 58 deletions
diff --git a/pjmedia/include/pjmedia/transport.h b/pjmedia/include/pjmedia/transport.h
index e3e664f7..9442d251 100644
--- a/pjmedia/include/pjmedia/transport.h
+++ b/pjmedia/include/pjmedia/transport.h
@@ -566,7 +566,7 @@ PJ_INLINE(void) pjmedia_transport_info_init(pjmedia_transport_info *info)
* for example to fill in the "c=" and "m=" line of local SDP.
*
* @param tp The transport.
- * @param info Media socket info to be initialized.
+ * @param info Media transport info to be initialized.
*
* @return PJ_SUCCESS on success.
*/
@@ -581,6 +581,29 @@ PJ_INLINE(pj_status_t) pjmedia_transport_get_info(pjmedia_transport *tp,
/**
+ * Utility API to get transport type specific info from the specified media
+ * transport info.
+ *
+ * @param info Media transport info.
+ * @param type Media transport type.
+ *
+ * @return Pointer to media transport specific info, or NULL if
+ * specific info for the transport type is not found.
+ */
+PJ_INLINE(void*) pjmedia_transport_info_get_spc_info(
+ pjmedia_transport_info *info,
+ pjmedia_transport_type type)
+{
+ unsigned i;
+ for (i = 0; i < info->specific_info_cnt; ++i) {
+ if (info->spc_info[i].type == type)
+ return (void*)info->spc_info[i].buffer;
+ }
+ return NULL;
+}
+
+
+/**
* Attach callbacks to be called on receipt of incoming RTP/RTCP packets.
* This is just a simple wrapper which calls <tt>attach()</tt> member of
* the transport.
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index bd72485f..79f6c1d3 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -3059,10 +3059,10 @@ static pj_bool_t check_ice_complete(pjsua_call *call, pj_bool_t *need_reinv)
unsigned i;
/* Check if ICE setup is complete and if it needs reinvite */
- for (i = 0; i < call->med_cnt && ice_complete; ++i) {
+ for (i = 0; i < call->med_cnt; ++i) {
pjsua_call_media *call_med = &call->media[i];
pjmedia_transport_info tpinfo;
- unsigned j;
+ pjmedia_ice_transport_info *ice_info;
if (call_med->tp_st == PJSUA_MED_TP_NULL ||
call_med->tp_st == PJSUA_MED_TP_DISABLED ||
@@ -3073,34 +3073,30 @@ static pj_bool_t check_ice_complete(pjsua_call *call, pj_bool_t *need_reinv)
pjmedia_transport_info_init(&tpinfo);
pjmedia_transport_get_info(call_med->tp, &tpinfo);
- for (j = 0; j < tpinfo.specific_info_cnt; ++j) {
- pjmedia_ice_transport_info *ice_info;
-
- if (tpinfo.spc_info[j].type != PJMEDIA_TRANSPORT_TYPE_ICE)
- continue;
-
- ice_info = (pjmedia_ice_transport_info*)tpinfo.spc_info[j].buffer;
-
- /* Check if ICE setup not completed yet */
- if (ice_info->sess_state < PJ_ICE_STRANS_STATE_RUNNING) {
- ice_complete = PJ_FALSE;
- break;
- }
-
- /* Check if ICE needs to send reinvite */
- if (!ice_need_reinv &&
- ice_info->sess_state == PJ_ICE_STRANS_STATE_RUNNING &&
- ice_info->role == PJ_ICE_SESS_ROLE_CONTROLLING)
+ ice_info = (pjmedia_ice_transport_info*)
+ pjmedia_transport_info_get_spc_info(
+ &tpinfo, PJMEDIA_TRANSPORT_TYPE_ICE);
+ if (!ice_info)
+ continue;
+
+ /* Check if ICE setup not completed yet */
+ if (ice_info->sess_state < PJ_ICE_STRANS_STATE_RUNNING) {
+ ice_complete = PJ_FALSE;
+ break;
+ }
+
+ /* Check if ICE needs to send reinvite */
+ if (!ice_need_reinv &&
+ ice_info->sess_state == PJ_ICE_STRANS_STATE_RUNNING &&
+ ice_info->role == PJ_ICE_SESS_ROLE_CONTROLLING)
+ {
+ pjsua_ice_config *cfg=&pjsua_var.acc[call->acc_id].cfg.ice_cfg;
+ if ((cfg->ice_always_update && !call->reinv_ice_sent) ||
+ pj_sockaddr_cmp(&tpinfo.sock_info.rtp_addr_name,
+ &call_med->rtp_addr))
{
- pjsua_ice_config *cfg=&pjsua_var.acc[call->acc_id].cfg.ice_cfg;
- if ((cfg->ice_always_update && !call->reinv_ice_sent) ||
- pj_sockaddr_cmp(&tpinfo.sock_info.rtp_addr_name,
- &call_med->rtp_addr))
- {
- ice_need_reinv = PJ_TRUE;
- }
+ ice_need_reinv = PJ_TRUE;
}
- break;
}
}
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 26a6cb70..d18703ca 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -2248,6 +2248,20 @@ static pj_bool_t match_codec_fmtp(const pjmedia_codec_fmtp *fmtp1,
#if PJSUA_MEDIA_HAS_PJMEDIA || PJSUA_THIRD_PARTY_STREAM_HAS_GET_INFO
+static pj_bool_t is_ice_running(pjmedia_transport *tp)
+{
+ pjmedia_transport_info tpinfo;
+ pjmedia_ice_transport_info *ice_info;
+
+ pjmedia_transport_info_init(&tpinfo);
+ pjmedia_transport_get_info(tp, &tpinfo);
+ ice_info = (pjmedia_ice_transport_info*)
+ pjmedia_transport_info_get_spc_info(&tpinfo,
+ PJMEDIA_TRANSPORT_TYPE_ICE);
+ return (ice_info && ice_info->sess_state == PJ_ICE_STRANS_STATE_RUNNING);
+}
+
+
static pj_bool_t is_media_changed(const pjsua_call *call,
unsigned med_idx,
const pjsua_stream_info *new_si_)
@@ -2287,9 +2301,15 @@ static pj_bool_t is_media_changed(const pjsua_call *call,
return (new_si->dir != PJMEDIA_DIR_NONE);
}
- /* Compare remote RTP address */
- if (pj_sockaddr_cmp(&old_si->rem_addr, &new_si->rem_addr))
+ /* Compare remote RTP address. If ICE is running, change in default
+ * address can happen after negotiation, this can be handled
+ * internally by ICE and does not need to cause media restart.
+ */
+ if (!is_ice_running(call_med->tp) &&
+ pj_sockaddr_cmp(&old_si->rem_addr, &new_si->rem_addr))
+ {
return PJ_TRUE;
+ }
/* Compare codec info */
if (pj_stricmp(&old_ci->encoding_name, &new_ci->encoding_name) ||
@@ -2343,9 +2363,15 @@ static pj_bool_t is_media_changed(const pjsua_call *call,
return (new_si->dir != PJMEDIA_DIR_NONE);
}
- /* Compare remote RTP address */
- if (pj_sockaddr_cmp(&old_si->rem_addr, &new_si->rem_addr))
+ /* Compare remote RTP address. If ICE is running, change in default
+ * address can happen after negotiation, this can be handled
+ * internally by ICE and does not need to cause media restart.
+ */
+ if (!is_ice_running(call_med->tp) &&
+ pj_sockaddr_cmp(&old_si->rem_addr, &new_si->rem_addr))
+ {
return PJ_TRUE;
+ }
/* Compare codec info */
if (pj_stricmp(&old_ci->encoding_name, &new_ci->encoding_name) ||
@@ -2554,6 +2580,7 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
} else {
pjmedia_transport_info tp_info;
+ pjmedia_srtp_info *srtp_info;
/* Start/restart media transport based on info in SDP */
status = pjmedia_transport_media_start(call_med->tp,
@@ -2572,19 +2599,11 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
/* Get remote SRTP usage policy */
pjmedia_transport_info_init(&tp_info);
pjmedia_transport_get_info(call_med->tp, &tp_info);
- if (tp_info.specific_info_cnt > 0) {
- unsigned i;
- for (i = 0; i < tp_info.specific_info_cnt; ++i) {
- if (tp_info.spc_info[i].type ==
- PJMEDIA_TRANSPORT_TYPE_SRTP)
- {
- pjmedia_srtp_info *srtp_info =
- (pjmedia_srtp_info*)tp_info.spc_info[i].buffer;
-
- call_med->rem_srtp_use = srtp_info->peer_use;
- break;
- }
- }
+ srtp_info = (pjmedia_srtp_info*)
+ pjmedia_transport_info_get_spc_info(
+ &tp_info, PJMEDIA_TRANSPORT_TYPE_SRTP);
+ if (srtp_info) {
+ call_med->rem_srtp_use = srtp_info->peer_use;
}
/* Update audio channel */
@@ -2691,6 +2710,7 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
} else {
pjmedia_transport_info tp_info;
+ pjmedia_srtp_info *srtp_info;
/* Start/restart media transport */
status = pjmedia_transport_media_start(call_med->tp,
@@ -2709,18 +2729,11 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
/* Get remote SRTP usage policy */
pjmedia_transport_info_init(&tp_info);
pjmedia_transport_get_info(call_med->tp, &tp_info);
- if (tp_info.specific_info_cnt > 0) {
- unsigned i;
- for (i = 0; i < tp_info.specific_info_cnt; ++i) {
- if (tp_info.spc_info[i].type ==
- PJMEDIA_TRANSPORT_TYPE_SRTP)
- {
- pjmedia_srtp_info *sri;
- sri=(pjmedia_srtp_info*)tp_info.spc_info[i].buffer;
- call_med->rem_srtp_use = sri->peer_use;
- break;
- }
- }
+ srtp_info = (pjmedia_srtp_info*)
+ pjmedia_transport_info_get_spc_info(
+ &tp_info, PJMEDIA_TRANSPORT_TYPE_SRTP);
+ if (srtp_info) {
+ call_med->rem_srtp_use = srtp_info->peer_use;
}
/* Update audio channel */