diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2008-05-02 15:01:10 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2008-05-02 15:01:10 +0000 |
commit | 97b27055e3a9649701ff157e0893ac2b24d232bf (patch) | |
tree | 51127a97a52bafe4f36c941768c917ae1bce4ef3 /pjmedia | |
parent | eff8a969db870c51c1d86f82384de086d9186b25 (diff) |
More ticket #513:
- Added RTCP XR features on stream: configurable RTCP XR sending interval, third-party destination for RTCP XR, and sending last RTCP XR packet when stream destroyed.
- Updated end system delay of RTCP XR: sound device latency estimated based on sound device implementation.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1945 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r-- | pjmedia/include/pjmedia/stream.h | 6 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/rtcp_xr.c | 21 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/stream.c | 110 |
3 files changed, 117 insertions, 20 deletions
diff --git a/pjmedia/include/pjmedia/stream.h b/pjmedia/include/pjmedia/stream.h index 159d03a1..551b90a9 100644 --- a/pjmedia/include/pjmedia/stream.h +++ b/pjmedia/include/pjmedia/stream.h @@ -98,6 +98,12 @@ struct pjmedia_stream_info #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) pj_bool_t rtcp_xr_enabled; /**< Specify whether RTCP XR is enabled.*/ + pj_uint32_t rtcp_xr_interval; /**< RTCP XR interval. */ + pj_sockaddr rtcp_xr_dest;/**<Additional remote RTCP XR address. + This is useful for third-party (e.g: + network monitor) to monitor the + stream. If sin_family is zero, + this will be ignored. */ #endif pjmedia_codec_info fmt; /**< Incoming codec format info. */ pjmedia_codec_param *param; /**< Optional codec param. */ diff --git a/pjmedia/src/pjmedia/rtcp_xr.c b/pjmedia/src/pjmedia/rtcp_xr.c index 27a726aa..7bb7cb53 100644 --- a/pjmedia/src/pjmedia/rtcp_xr.c +++ b/pjmedia/src/pjmedia/rtcp_xr.c @@ -269,6 +269,7 @@ PJ_DEF(void) pjmedia_rtcp_build_rtcp_xr( pjmedia_rtcp_xr_session *sess, pj_uint32_t c32; pj_uint32_t c33; pj_uint32_t ctotal, p32, p23, m; + unsigned est_extra_delay; r = (pjmedia_rtcp_xr_rb_voip_mtc*) &sess->pkt.buf[size]; pj_bzero(r, sizeof(pjmedia_rtcp_xr_rb_voip_mtc)); @@ -341,16 +342,26 @@ PJ_DEF(void) pjmedia_rtcp_build_rtcp_xr( pjmedia_rtcp_xr_session *sess, sess->stat.rx.voip_mtc.rnd_trip_delay = (pj_uint16_t) (sess->rtcp_session->stat.rtt.last / 1000); - /* End system delay estimation = RTT/2 + current jitter buffer size + - * EXTRA + /* End system delay = RTT/2 + current jitter buffer size + + * EXTRA (estimated extra delay) * EXTRA will cover additional delay introduced by other components of * audio engine, e.g: sound device, codec, AEC, PLC, WSOLA. * Since it is difficult to get the exact value of EXTRA, estimation - * is taken to be totally around 50 ms. + * is taken to be totally around 30ms + sound device latency. */ + est_extra_delay = 30 + +#if PJMEDIA_SOUND_IMPLEMENTATION==PJMEDIA_SOUND_PORTAUDIO_SOUND + PJMEDIA_PASOUND_MAX_LATENCY +#elif PJMEDIA_SOUND_IMPLEMENTATION==PJMEDIA_SOUND_NULL_SOUND + 0 +#else + (PJMEDIA_SOUND_BUFFER_COUNT * 15) +#endif + ; sess->stat.rx.voip_mtc.end_sys_delay = (pj_uint16_t) - (sess->stat.rx.voip_mtc.rnd_trip_delay / 2 + - sess->stat.rx.voip_mtc.jb_nom + 50); + (sess->stat.rx.voip_mtc.rnd_trip_delay / 2 + + sess->stat.rx.voip_mtc.jb_nom + + est_extra_delay); /* Generate block contents */ r->ssrc = pj_htonl(sess->rtcp_session->peer_ssrc); diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c index d826ab70..edf8a230 100644 --- a/pjmedia/src/pjmedia/stream.c +++ b/pjmedia/src/pjmedia/stream.c @@ -157,6 +157,16 @@ struct pjmedia_stream checking */ #endif +#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) + pj_uint32_t rtcp_xr_last_tx; /**< RTCP XR tx time + in timestamp. */ + pj_uint32_t rtcp_xr_interval; /**< Interval, in timestamp. */ + pj_sockaddr rtcp_xr_dest; /**< Additional remote RTCP XR + dest. If sin_family is + zero, it will be ignored*/ + unsigned rtcp_xr_dest_len; /**< Length of RTCP XR dest + address */ +#endif }; @@ -467,18 +477,29 @@ static void check_tx_rtcp(pjmedia_stream *stream, pj_uint32_t timestamp) pjmedia_rtcp_build_rtcp(&stream->rtcp, &rtcp_pkt, &len); - (*stream->transport->op->send_rtcp)(stream->transport, - rtcp_pkt, len); + pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len); + + stream->rtcp_last_tx = timestamp; + } #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) - /* Temporarily always send RTCP XR after RTCP */ - if (stream->rtcp.xr_enabled) + if (stream->rtcp.xr_enabled) { + + if (stream->rtcp_xr_last_tx == 0) { + + stream->rtcp_xr_last_tx = timestamp; + + } else if (timestamp - stream->rtcp_xr_last_tx >= + stream->rtcp_xr_interval) { int i; pjmedia_jb_state jb_state; + void *rtcp_pkt; + int len; + /* Update RTCP XR with current JB states */ pjmedia_jbuf_get_state(stream->jb, &jb_state); - + i = jb_state.size * stream->codec_param.info.frm_ptime; pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, PJMEDIA_RTCP_XR_INFO_JB_NOM, @@ -489,16 +510,26 @@ static void check_tx_rtcp(pjmedia_stream *stream, pj_uint32_t timestamp) PJMEDIA_RTCP_XR_INFO_JB_MAX, i); + /* Build RTCP XR packet */ pjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0, &rtcp_pkt, &len); - (*stream->transport->op->send_rtcp)(stream->transport, - rtcp_pkt, len); - } -#endif + /* Send the RTCP XR to remote address */ + pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len); - stream->rtcp_last_tx = timestamp; + /* Send the RTCP XR to third-party destination if specified */ + if (stream->rtcp_xr_dest_len) { + pjmedia_transport_send_rtcp2(stream->transport, + &stream->rtcp_xr_dest, + stream->rtcp_xr_dest_len, + rtcp_pkt, len); + } + + /* Update last tx RTCP XR */ + stream->rtcp_xr_last_tx = timestamp; + } } +#endif } @@ -767,11 +798,8 @@ static pj_status_t put_frame_imp( pjmedia_port *port, stream->is_streaming = PJ_TRUE; /* Send the RTP packet to the transport. */ - (*stream->transport->op->send_rtp)(stream->transport, - channel->out_pkt, - frame_out.size + - sizeof(pjmedia_rtp_hdr)); - + pjmedia_transport_send_rtp(stream->transport, channel->out_pkt, + frame_out.size + sizeof(pjmedia_rtp_hdr)); /* Update stat */ pjmedia_rtcp_tx_rtp(&stream->rtcp, frame_out.size); @@ -1564,6 +1592,21 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt, pjmedia_rtcp_enable_xr(&stream->rtcp, PJ_TRUE); + /* Set RTCP XR TX interval */ + if (info->rtcp_xr_interval != 0) + stream->rtcp_xr_interval = info->rtcp_xr_interval; + else + stream->rtcp_xr_interval = (PJMEDIA_RTCP_INTERVAL + + (pj_rand() % 8000)) * + info->fmt.clock_rate / 1000; + + /* Additional third-party RTCP XR destination */ + if (info->rtcp_xr_dest.addr.sa_family != 0) { + stream->rtcp_xr_dest_len = pj_sockaddr_get_len(&info->rtcp_xr_dest); + pj_memcpy(&stream->rtcp_xr_dest, &info->rtcp_xr_dest, + stream->rtcp_xr_dest_len); + } + /* jitter buffer adaptive info */ i = PJMEDIA_RTCP_XR_JB_ADAPTIVE; pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, @@ -1619,6 +1662,43 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream ) PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); +#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) + /* Send RTCP XR on stream destroy */ + if (stream->rtcp.xr_enabled) { + int i; + pjmedia_jb_state jb_state; + void *rtcp_pkt; + int len; + + /* Update RTCP XR with current JB states */ + pjmedia_jbuf_get_state(stream->jb, &jb_state); + + i = jb_state.size * stream->codec_param.info.frm_ptime; + pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, + PJMEDIA_RTCP_XR_INFO_JB_NOM, + i); + + i = jb_state.max_size* stream->codec_param.info.frm_ptime; + pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, + PJMEDIA_RTCP_XR_INFO_JB_MAX, + i); + + /* Build RTCP XR packet */ + pjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0, + &rtcp_pkt, &len); + + /* Send the RTCP XR to remote address */ + pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len); + + /* Send the RTCP XR to third-party destination if specified */ + if (stream->rtcp_xr_dest_len) { + pjmedia_transport_send_rtcp2(stream->transport, + &stream->rtcp_xr_dest, + stream->rtcp_xr_dest_len, + rtcp_pkt, len); + } + } +#endif /* Detach from transport * MUST NOT hold stream mutex while detaching from transport, as |