summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2010-06-26 04:43:50 +0000
committerNanang Izzuddin <nanang@teluu.com>2010-06-26 04:43:50 +0000
commitcb0e240d2210d391514286965cc20a05b6c65b6a (patch)
treeb92b5cd7dbdaf40b80da4411a95417c97030ae6b
parent6616964e3d018360c33b8c3b884e2f7902eca438 (diff)
Fix #740:
- Fixed zeroed/unset RTP timestamp in RTCP sender report. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3224 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia/rtcp.h33
-rw-r--r--pjmedia/src/pjmedia/rtcp.c50
-rw-r--r--pjmedia/src/pjmedia/stream.c40
3 files changed, 102 insertions, 21 deletions
diff --git a/pjmedia/include/pjmedia/rtcp.h b/pjmedia/include/pjmedia/rtcp.h
index a443add4..df6e1848 100644
--- a/pjmedia/include/pjmedia/rtcp.h
+++ b/pjmedia/include/pjmedia/rtcp.h
@@ -246,6 +246,7 @@ struct pjmedia_rtcp_session
pj_time_val tv_base; /**< Base time, in seconds. */
pj_timestamp ts_base; /**< Base system timestamp. */
pj_timestamp ts_freq; /**< System timestamp frequency. */
+ pj_uint32_t rtp_ts_base;/**< Base RTP timestamp. */
pj_uint32_t rx_lsr; /**< NTP ts in last SR received */
pj_timestamp rx_lsr_time;/**< Time when last SR is received */
@@ -274,6 +275,28 @@ typedef struct pjmedia_rtcp_session pjmedia_rtcp_session;
/**
+ * RTCP session settings.
+ */
+typedef struct pjmedia_rtcp_session_setting
+{
+ char *name; /**< RTCP session name. */
+ unsigned clock_rate; /**< Sequence. */
+ unsigned samples_per_frame; /**< Timestamp. */
+ pj_uint32_t ssrc; /**< Sender SSRC. */
+ pj_uint32_t rtp_ts_base; /**< Base RTP timestamp. */
+} pjmedia_rtcp_session_setting;
+
+
+/**
+ * Initialize RTCP session setting.
+ *
+ * @param settings The RTCP session setting to be initialized.
+ */
+PJ_DECL(void) pjmedia_rtcp_session_setting_default(
+ pjmedia_rtcp_session_setting *settings);
+
+
+/**
* Initialize RTCP session.
*
* @param session The session
@@ -291,6 +314,16 @@ PJ_DECL(void) pjmedia_rtcp_init( pjmedia_rtcp_session *session,
/**
+ * Initialize RTCP session.
+ *
+ * @param session The session
+ * @param settings The RTCP session settings.
+ */
+PJ_DECL(void) pjmedia_rtcp_init2(pjmedia_rtcp_session *session,
+ const pjmedia_rtcp_session_setting *settings);
+
+
+/**
* Utility function to retrieve current NTP timestamp.
*
* @param sess RTCP session.
diff --git a/pjmedia/src/pjmedia/rtcp.c b/pjmedia/src/pjmedia/rtcp.c
index 3dd7e9a1..3c2de9e3 100644
--- a/pjmedia/src/pjmedia/rtcp.c
+++ b/pjmedia/src/pjmedia/rtcp.c
@@ -125,12 +125,43 @@ PJ_DEF(pj_status_t) pjmedia_rtcp_get_ntp_time(const pjmedia_rtcp_session *sess,
}
+/*
+ * Initialize RTCP session setting.
+ */
+PJ_DEF(void) pjmedia_rtcp_session_setting_default(
+ pjmedia_rtcp_session_setting *settings)
+{
+ pj_bzero(&settings, sizeof(*settings));
+}
+
+
+/*
+ * Initialize RTCP session.
+ */
PJ_DEF(void) pjmedia_rtcp_init(pjmedia_rtcp_session *sess,
char *name,
unsigned clock_rate,
unsigned samples_per_frame,
pj_uint32_t ssrc)
{
+ pjmedia_rtcp_session_setting settings;
+
+ pjmedia_rtcp_session_setting_default(&settings);
+ settings.name = name;
+ settings.clock_rate = clock_rate;
+ settings.samples_per_frame = samples_per_frame;
+ settings.ssrc = ssrc;
+
+ pjmedia_rtcp_init2(sess, &settings);
+}
+
+
+/*
+ * Initialize RTCP session.
+ */
+PJ_DEF(void) pjmedia_rtcp_init2( pjmedia_rtcp_session *sess,
+ const pjmedia_rtcp_session_setting *settings)
+{
pjmedia_rtcp_sr_pkt *sr_pkt = &sess->rtcp_sr_pkt;
pj_time_val now;
@@ -141,18 +172,18 @@ PJ_DEF(void) pjmedia_rtcp_init(pjmedia_rtcp_session *sess,
sess->rtp_last_ts = (unsigned)-1;
/* Name */
- sess->name = name ? name : (char*)THIS_FILE,
+ sess->name = settings->name ? settings->name : (char*)THIS_FILE;
/* Set clock rate */
- sess->clock_rate = clock_rate;
- sess->pkt_size = samples_per_frame;
+ sess->clock_rate = settings->clock_rate;
+ sess->pkt_size = settings->samples_per_frame;
/* Init common RTCP SR header */
sr_pkt->common.version = 2;
sr_pkt->common.count = 1;
sr_pkt->common.pt = RTCP_SR;
sr_pkt->common.length = pj_htons(12);
- sr_pkt->common.ssrc = pj_htonl(ssrc);
+ sr_pkt->common.ssrc = pj_htonl(settings->ssrc);
/* Copy to RTCP RR header */
pj_memcpy(&sess->rtcp_rr_pkt.common, &sr_pkt->common,
@@ -166,6 +197,7 @@ PJ_DEF(void) pjmedia_rtcp_init(pjmedia_rtcp_session *sess,
sess->stat.start = now;
pj_get_timestamp(&sess->ts_base);
pj_get_timestamp_freq(&sess->ts_freq);
+ sess->rtp_ts_base = settings->rtp_ts_base;
/* Initialize statistics states */
pj_math_stat_init(&sess->stat.rtt);
@@ -571,6 +603,8 @@ PJ_DEF(void) pjmedia_rtcp_build_rtcp(pjmedia_rtcp_session *sess,
* sent RTCP SR.
*/
if (sess->stat.tx.pkt != pj_ntohl(sess->rtcp_sr_pkt.sr.sender_pcount)) {
+ pj_time_val ts_time;
+ pj_uint32_t rtp_ts;
/* So we should send RTCP SR */
*ret_p_pkt = (void*) &sess->rtcp_sr_pkt;
@@ -589,6 +623,14 @@ PJ_DEF(void) pjmedia_rtcp_build_rtcp(pjmedia_rtcp_session *sess,
sr->ntp_sec = pj_htonl(ntp.hi);
sr->ntp_frac = pj_htonl(ntp.lo);
+ /* Fill in RTP timestamp (corresponds to NTP timestamp) in SR. */
+ ts_time.sec = ntp.hi - sess->tv_base.sec - JAN_1970;
+ ts_time.msec = (long)(ntp.lo * 1000.0 / 0xFFFFFFFF);
+ rtp_ts = sess->rtp_ts_base +
+ (pj_uint32_t)(sess->clock_rate*ts_time.sec) +
+ (pj_uint32_t)(sess->clock_rate*ts_time.msec/1000);
+ sr->rtp_ts = pj_htonl(rtp_ts);
+
TRACE_((sess->name, "TX RTCP SR: ntp_ts=%p",
((ntp.hi & 0xFFFF) << 16) + ((ntp.lo & 0xFFFF0000)
>> 16)));
diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c
index c7c0db73..ba5fad5c 100644
--- a/pjmedia/src/pjmedia/stream.c
+++ b/pjmedia/src/pjmedia/stream.c
@@ -2121,28 +2121,11 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
stream->rtp_rx_ts_len_per_frame = stream->port.info.samples_per_frame /
stream->codec_param.info.channel_cnt;
- /* Init RTCP session: */
-
- /* Special case for G.722 */
if (info->fmt.pt == PJMEDIA_RTP_PT_G722) {
- pjmedia_rtcp_init(&stream->rtcp, stream->port.info.name.ptr,
- 8000,
- 160,
- info->ssrc);
stream->has_g722_mpeg_bug = PJ_TRUE;
/* RTP clock rate = 1/2 real clock rate */
stream->rtp_tx_ts_len_per_pkt >>= 1;
- } else {
- pjmedia_rtcp_init(&stream->rtcp, stream->port.info.name.ptr,
- info->fmt.clock_rate,
- stream->port.info.samples_per_frame,
- info->ssrc);
}
-#else
- pjmedia_rtcp_init(&stream->rtcp, stream->port.info.name.ptr,
- info->fmt.clock_rate,
- stream->port.info.samples_per_frame,
- info->ssrc);
#endif
/* Init jitter buffer parameters: */
@@ -2198,6 +2181,29 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
goto err_cleanup;
+ /* Init RTCP session: */
+
+ {
+ pjmedia_rtcp_session_setting rtcp_setting;
+
+ pjmedia_rtcp_session_setting_default(&rtcp_setting);
+ rtcp_setting.name = stream->port.info.name.ptr;
+ rtcp_setting.ssrc = info->ssrc;
+ rtcp_setting.rtp_ts_base = pj_ntohl(stream->enc->rtp.out_hdr.ts);
+ rtcp_setting.clock_rate = info->fmt.clock_rate;
+ rtcp_setting.samples_per_frame = stream->port.info.samples_per_frame;
+
+#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
+ /* Special case for G.722 */
+ if (info->fmt.pt == PJMEDIA_RTP_PT_G722) {
+ rtcp_setting.clock_rate = 8000;
+ rtcp_setting.samples_per_frame = 160;
+ }
+#endif
+
+ pjmedia_rtcp_init2(&stream->rtcp, &rtcp_setting);
+ }
+
/* Only attach transport when stream is ready. */
status = pjmedia_transport_attach(tp, stream, &info->rem_addr,
&info->rem_rtcp,