diff options
-rw-r--r-- | pjmedia/include/pjmedia/session.h | 20 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/stream.h | 23 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/session.c | 34 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/stream.c | 93 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 11 |
5 files changed, 154 insertions, 27 deletions
diff --git a/pjmedia/include/pjmedia/session.h b/pjmedia/include/pjmedia/session.h index efab853a..44238c56 100644 --- a/pjmedia/include/pjmedia/session.h +++ b/pjmedia/include/pjmedia/session.h @@ -232,6 +232,26 @@ PJ_DECL(pj_status_t) pjmedia_session_resume_stream(pjmedia_session *session, pjmedia_dir dir); /** + * Send RTCP SDES for the session. + * + * @param session The media session. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) +pjmedia_session_send_rtcp_sdes( const pjmedia_session *session ); + +/** + * Send RTCP BYE for the session. + * + * @param session The media session. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) +pjmedia_session_send_rtcp_bye( const pjmedia_session *session ); + +/** * Enumerate media streams in the session. * * @param session The media session. diff --git a/pjmedia/include/pjmedia/stream.h b/pjmedia/include/pjmedia/stream.h index 9e1976e9..b1cd6d39 100644 --- a/pjmedia/include/pjmedia/stream.h +++ b/pjmedia/include/pjmedia/stream.h @@ -133,6 +133,9 @@ struct pjmedia_stream_info (see #PJMEDIA_STREAM_ENABLE_KA) is enabled? */ #endif + pj_bool_t rtcp_sdes_bye_disabled; + /**< Disable automatic sending of RTCP + SDES and BYE. */ }; @@ -372,6 +375,26 @@ pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream, void *user_data); /** + * Send RTCP SDES for the media stream. + * + * @param stream The media stream. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) +pjmedia_stream_send_rtcp_sdes( pjmedia_stream *stream ); + +/** + * Send RTCP BYE for the media stream. + * + * @param stream The media stream. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) +pjmedia_stream_send_rtcp_bye( pjmedia_stream *stream ); + +/** * @} */ diff --git a/pjmedia/src/pjmedia/session.c b/pjmedia/src/pjmedia/session.c index 34dc19fc..787cbb4c 100644 --- a/pjmedia/src/pjmedia/session.c +++ b/pjmedia/src/pjmedia/session.c @@ -813,6 +813,40 @@ PJ_DEF(pj_status_t) pjmedia_session_resume_stream( pjmedia_session *session, } /** + * Send RTCP SDES for the session. + */ +PJ_DEF(pj_status_t) +pjmedia_session_send_rtcp_sdes( const pjmedia_session *session ) +{ + unsigned i; + + PJ_ASSERT_RETURN(session, PJ_EINVAL); + + for (i=0; i<session->stream_cnt; ++i) { + pjmedia_stream_send_rtcp_sdes(session->stream[i]); + } + + return PJ_SUCCESS; +} + +/** + * Send RTCP BYE for the session. + */ +PJ_DEF(pj_status_t) +pjmedia_session_send_rtcp_bye( const pjmedia_session *session ) +{ + unsigned i; + + PJ_ASSERT_RETURN(session, PJ_EINVAL); + + for (i=0; i<session->stream_cnt; ++i) { + pjmedia_stream_send_rtcp_bye(session->stream[i]); + } + + return PJ_SUCCESS; +} + +/** * Enumerate media stream in the session. */ PJ_DEF(pj_status_t) pjmedia_session_enum_streams(const pjmedia_session *session, diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c index 42761c33..61e33d4b 100644 --- a/pjmedia/src/pjmedia/stream.c +++ b/pjmedia/src/pjmedia/stream.c @@ -143,6 +143,7 @@ struct pjmedia_stream pj_uint32_t rtcp_last_tx; /**< RTCP tx time in timestamp */ pj_uint32_t rtcp_interval; /**< Interval, in timestamp. */ pj_bool_t initial_rr; /**< Initial RTCP RR sent */ + pj_bool_t rtcp_sdes_bye_disabled;/**< Send RTCP SDES/BYE?*/ /* RFC 2833 DTMF transmission queue: */ int tx_event_pt; /**< Outgoing pt for dtmf. */ @@ -1826,19 +1827,24 @@ on_return: /* Build RR or SR */ pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len); - pkt = (pj_uint8_t*) stream->enc->out_pkt; - pj_memcpy(pkt, sr_rr_pkt, len); - pkt += len; - - /* Append SDES */ - len = create_rtcp_sdes(stream, (pj_uint8_t*)pkt, - stream->enc->out_pkt_size - len); - if (len > 0) { - pkt += len; - len = ((pj_uint8_t*)pkt) - ((pj_uint8_t*)stream->enc->out_pkt); - pjmedia_transport_send_rtcp(stream->transport, - stream->enc->out_pkt, len); - } + + if (!stream->rtcp_sdes_bye_disabled) { + pkt = (pj_uint8_t*) stream->enc->out_pkt; + pj_memcpy(pkt, sr_rr_pkt, len); + pkt += len; + + /* Append SDES */ + len = create_rtcp_sdes(stream, (pj_uint8_t*)pkt, + stream->enc->out_pkt_size - len); + if (len > 0) { + pkt += len; + len = ((pj_uint8_t*)pkt) - ((pj_uint8_t*)stream->enc->out_pkt); + pjmedia_transport_send_rtcp(stream->transport, + stream->enc->out_pkt, len); + } + } else { + pjmedia_transport_send_rtcp(stream->transport, ss_rr_pkt, len); + } stream->initial_rr = PJ_TRUE; } @@ -1954,7 +1960,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt, enum { M = 32 }; pjmedia_stream *stream; pj_str_t name; - unsigned jb_init, jb_max, jb_min_pre, jb_max_pre, len; + unsigned jb_init, jb_max, jb_min_pre, jb_max_pre; char *p; pj_status_t status; @@ -1992,6 +1998,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt, stream->user_data = user_data; stream->rtcp_interval = (PJMEDIA_RTCP_INTERVAL-500 + (pj_rand()%1000)) * info->fmt.clock_rate / 1000; + stream->rtcp_sdes_bye_disabled = info->rtcp_sdes_bye_disabled; stream->tx_event_pt = info->tx_event_pt ? info->tx_event_pt : -1; stream->rx_event_pt = info->rx_event_pt ? info->rx_event_pt : -1; @@ -2305,11 +2312,8 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt, #endif /* Send RTCP SDES */ - len = create_rtcp_sdes(stream, (pj_uint8_t*)stream->enc->out_pkt, - stream->enc->out_pkt_size); - if (len != 0) { - pjmedia_transport_send_rtcp(stream->transport, - stream->enc->out_pkt, len); + if (!stream->rtcp_sdes_bye_disabled) { + pjmedia_stream_send_rtcp_sdes(stream); } #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0 @@ -2364,7 +2368,6 @@ err_cleanup: */ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream ) { - unsigned len; PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) @@ -2406,13 +2409,8 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream ) #endif /* Send RTCP BYE */ - if (stream->enc && stream->transport) { - len = create_rtcp_bye(stream, (pj_uint8_t*)stream->enc->out_pkt, - stream->enc->out_pkt_size); - if (len != 0) { - pjmedia_transport_send_rtcp(stream->transport, - stream->enc->out_pkt, len); - } + if (!stream->rtcp_sdes_bye_disabled) { + pjmedia_stream_send_rtcp_bye(stream); } /* Detach from transport @@ -2760,3 +2758,44 @@ PJ_DEF(pj_status_t) pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream, return PJ_SUCCESS; } +/* + * Send RTCP SDES. + */ +PJ_DEF(pj_status_t) +pjmedia_stream_send_rtcp_sdes( pjmedia_stream *stream ) +{ + unsigned len; + + PJ_ASSERT_RETURN(stream, PJ_EINVAL); + + len = create_rtcp_sdes(stream, (pj_uint8_t*)stream->enc->out_pkt, + stream->enc->out_pkt_size); + if (len != 0) { + return pjmedia_transport_send_rtcp(stream->transport, + stream->enc->out_pkt, len); + } + + return PJ_SUCCESS; +} + +/* + * Send RTCP BYE. + */ +PJ_DEF(pj_status_t) +pjmedia_stream_send_rtcp_bye( pjmedia_stream *stream ) +{ + PJ_ASSERT_RETURN(stream, PJ_EINVAL); + + if (stream->enc && stream->transport) { + unsigned len; + + len = create_rtcp_bye(stream, (pj_uint8_t*)stream->enc->out_pkt, + stream->enc->out_pkt_size); + if (len != 0) { + return pjmedia_transport_send_rtcp(stream->transport, + stream->enc->out_pkt, len); + } + } + + return PJ_SUCCESS; +} diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index 2eced3d9..f6791131 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -1530,6 +1530,9 @@ pj_status_t pjsua_media_channel_deinit(pjsua_call_id call_id) { pjsua_call *call = &pjsua_var.calls[call_id]; + if (call->session) + pjmedia_session_send_rtcp_bye(call->session); + stop_media_session(call_id); if (call->med_tp_st != PJSUA_MED_TP_IDLE) { @@ -1573,6 +1576,7 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id, const pjmedia_sdp_session *local_sdp, const pjmedia_sdp_session *remote_sdp) { + unsigned i; int prev_media_st = 0; pjsua_call *call = &pjsua_var.calls[call_id]; pjmedia_session_info sess_info; @@ -1598,6 +1602,10 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id, if (status != PJ_SUCCESS) return status; + for (i = 0; i < sess_info.stream_cnt; ++i) { + sess_info.stream_info[i].rtcp_sdes_bye_disabled = PJ_TRUE; + } + /* Update audio index from the negotiated SDP */ call->audio_idx = find_audio_index(local_sdp, PJ_TRUE); @@ -1717,6 +1725,9 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id, return status; } + if (prev_media_st == PJSUA_CALL_MEDIA_NONE) + pjmedia_session_send_rtcp_sdes(call->session); + /* If DTMF callback is installed by application, install our * callback to the session. */ |