diff --git a/pjlib/include/pj/config.h b/pjlib/include/pj/config.h index e7721d6627..063d6eb375 100644 --- a/pjlib/include/pj/config.h +++ b/pjlib/include/pj/config.h @@ -1496,13 +1496,13 @@ PJ_BEGIN_DECL #define PJ_VERSION_NUM_MINOR 14 /** PJLIB version revision number. */ -#define PJ_VERSION_NUM_REV 0 +#define PJ_VERSION_NUM_REV 1 /** * Extra suffix for the version (e.g. "-trunk"), or empty for * web release version. */ -#define PJ_VERSION_NUM_EXTRA "-7" +#define PJ_VERSION_NUM_EXTRA "-1" /** * PJLIB version number consists of three bytes with the following format: diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c index 1de648eeef..ecf932e62a 100644 --- a/pjmedia/src/pjmedia/stream.c +++ b/pjmedia/src/pjmedia/stream.c @@ -1113,10 +1113,11 @@ static pj_status_t send_rtcp(pjmedia_stream *stream, pj_status_t status; /* We need to prevent data race since there is only a single instance - * of rtcp packet buffer. Let's just use the JB mutex for this instead - * of creating a separate lock. + * of rtcp packet buffer. And to avoid deadlock with media transport, + * we use the transport's group lock. */ - pj_mutex_lock(stream->jb_mutex); + if (stream->transport->grp_lock) + pj_grp_lock_acquire(stream->transport->grp_lock); /* Build RTCP RR/SR packet */ pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len); @@ -1237,7 +1238,8 @@ static pj_status_t send_rtcp(pjmedia_stream *stream, } } - pj_mutex_unlock(stream->jb_mutex); + if (stream->transport->grp_lock) + pj_grp_lock_release(stream->transport->grp_lock); return status; } @@ -3106,7 +3108,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream ) PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); /* Send RTCP BYE (also SDES & XR) */ - if (stream->transport && stream->jb_mutex && !stream->rtcp_sdes_bye_disabled) { + if (stream->transport && !stream->rtcp_sdes_bye_disabled) { #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) send_rtcp(stream, PJ_TRUE, PJ_TRUE, stream->rtcp.xr_enabled, PJ_FALSE); #else diff --git a/pjmedia/src/pjmedia/transport_loop.c b/pjmedia/src/pjmedia/transport_loop.c index 37e6f18cd5..df49a3655c 100644 --- a/pjmedia/src/pjmedia/transport_loop.c +++ b/pjmedia/src/pjmedia/transport_loop.c @@ -187,6 +187,7 @@ pjmedia_transport_loop_create2(pjmedia_endpt *endpt, if (status != PJ_SUCCESS) return status; + tp->base.grp_lock = grp_lock; pj_grp_lock_add_ref(grp_lock); pj_grp_lock_add_handler(grp_lock, pool, tp, &tp_loop_on_destroy); diff --git a/pjmedia/src/pjmedia/vid_stream.c b/pjmedia/src/pjmedia/vid_stream.c index cbd086c022..482036243d 100644 --- a/pjmedia/src/pjmedia/vid_stream.c +++ b/pjmedia/src/pjmedia/vid_stream.c @@ -584,7 +584,12 @@ static pj_status_t send_rtcp(pjmedia_vid_stream *stream, int len, max_len; pj_status_t status; - pj_grp_lock_acquire( stream->grp_lock ); + + /* To avoid deadlock with media transport, we use the transport's + * group lock. + */ + if (stream->transport->grp_lock) + pj_grp_lock_acquire( stream->transport->grp_lock ); /* Build RTCP RR/SR packet */ pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len); @@ -667,7 +672,8 @@ static pj_status_t send_rtcp(pjmedia_vid_stream *stream, } } - pj_grp_lock_release( stream->grp_lock ); + if (stream->transport->grp_lock) + pj_grp_lock_release( stream->transport->grp_lock ); return status; } @@ -2191,7 +2197,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_stream_destroy( pjmedia_vid_stream *stream ) pjmedia_event_unsubscribe(NULL, &stream_event_cb, stream, &stream->rtcp); /* Send RTCP BYE (also SDES) */ - if (stream->transport && stream->grp_lock && !stream->rtcp_sdes_bye_disabled) { + if (stream->transport && !stream->rtcp_sdes_bye_disabled) { send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_FALSE, PJ_FALSE); } diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index 2ee412160d..d3d7725897 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -2756,8 +2756,8 @@ PJ_DEF(pj_status_t) pjsua_call_answer2(pjsua_call_id call_id, if (status != PJ_SUCCESS) goto on_return; - if (call->inv->role == PJSIP_ROLE_UAC || - !call->inv->invite_tsx || + if (!call->inv->invite_tsx || + call->inv->invite_tsx->role != PJSIP_ROLE_UAS || call->inv->invite_tsx->state >= PJSIP_TSX_STATE_COMPLETED) { PJ_LOG(3,(THIS_FILE, "Unable to answer call (no incoming INVITE or " diff --git a/version.mak b/version.mak index 7ae5d77dba..b49d3383ff 100644 --- a/version.mak +++ b/version.mak @@ -1,8 +1,8 @@ # Don't change the "export PJ_VERSION_xxx" style, they are parsed by setup.py export PJ_VERSION_MAJOR := 2 export PJ_VERSION_MINOR := 14 -export PJ_VERSION_REV := -export PJ_VERSION_SUFFIX := -7 +export PJ_VERSION_REV := 1 +export PJ_VERSION_SUFFIX := -1 export PJ_VERSION := $(PJ_VERSION_MAJOR).$(PJ_VERSION_MINOR)