summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2008-08-26 16:51:28 +0000
committerNanang Izzuddin <nanang@teluu.com>2008-08-26 16:51:28 +0000
commit8f801ac496cf978d41daf150c9d9b492b78cebac (patch)
treed9e33eee205b6c5110a077e9828e51c94b5011c5
parent472c21109bff70d66f59bd113b4031fde29a8a86 (diff)
Ticket #602:
- Introduced new API pjmedia_rtp_session_init2() to enable intializing RTP session with non-default initial settings - Updated stream so it can be created with non-default initial RTP settings. - Updated pjsua-lib to make sure RTP timestamp and sequence contigue when stream session is restarted. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2241 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia/rtcp.h3
-rw-r--r--pjmedia/include/pjmedia/rtp.h34
-rw-r--r--pjmedia/include/pjmedia/stream.h7
-rw-r--r--pjmedia/src/pjmedia/rtp.c27
-rw-r--r--pjmedia/src/pjmedia/stream.c15
-rw-r--r--pjsip/include/pjsua-lib/pjsua_internal.h7
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c3
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c26
8 files changed, 121 insertions, 1 deletions
diff --git a/pjmedia/include/pjmedia/rtcp.h b/pjmedia/include/pjmedia/rtcp.h
index e0f3cc5d..0afac656 100644
--- a/pjmedia/include/pjmedia/rtcp.h
+++ b/pjmedia/include/pjmedia/rtcp.h
@@ -210,6 +210,9 @@ struct pjmedia_rtcp_stat
pjmedia_rtcp_stream_stat rx; /**< Decoder stream statistics. */
pj_math_stat rtt; /**< Round trip delay statistic(in usec)*/
+
+ pj_uint32_t rtp_tx_last_ts; /**< Last TX RTP timestamp. */
+ pj_uint16_t rtp_tx_last_seq;/**< Last TX RTP sequence. */
};
diff --git a/pjmedia/include/pjmedia/rtp.h b/pjmedia/include/pjmedia/rtp.h
index dd8e02ba..44163232 100644
--- a/pjmedia/include/pjmedia/rtp.h
+++ b/pjmedia/include/pjmedia/rtp.h
@@ -220,6 +220,26 @@ struct pjmedia_rtp_status
value will be one. */
};
+
+/**
+ * RTP session settings.
+ */
+typedef struct pjmedia_rtp_session_setting
+{
+ pj_uint8_t flags; /**< Bitmask flags to specify whether such
+ field is set. Bitmask contents are:
+ (bit #0 is LSB)
+ bit #0: default payload type
+ bit #1: sender SSRC
+ bit #2: sequence
+ bit #3: timestamp */
+ int default_pt; /**< Default payload type. */
+ pj_uint32_t sender_ssrc; /**< Sender SSRC. */
+ pj_uint16_t seq; /**< Sequence. */
+ pj_uint32_t ts; /**< Timestamp. */
+} pjmedia_rtp_session_setting;
+
+
/**
* @see pjmedia_rtp_status
*/
@@ -240,6 +260,20 @@ PJ_DECL(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses,
pj_uint32_t sender_ssrc );
/**
+ * This function will initialize the RTP session according to given parameters
+ * defined in RTP session settings.
+ *
+ * @param ses The session.
+ * @param settings RTP session settings.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtp_session_init2(
+ pjmedia_rtp_session *ses,
+ pjmedia_rtp_session_setting settings);
+
+
+/**
* Create the RTP header based on arguments and current state of the RTP
* session.
*
diff --git a/pjmedia/include/pjmedia/stream.h b/pjmedia/include/pjmedia/stream.h
index b14ef377..bb82698f 100644
--- a/pjmedia/include/pjmedia/stream.h
+++ b/pjmedia/include/pjmedia/stream.h
@@ -112,6 +112,13 @@ struct pjmedia_stream_info
int tx_event_pt;/**< Outgoing pt for telephone-events. */
int rx_event_pt;/**< Incoming pt for telephone-events. */
pj_uint32_t ssrc; /**< RTP SSRC. */
+ pj_uint32_t rtp_ts; /**< Initial RTP timestamp. */
+ pj_uint16_t rtp_seq; /**< Initial RTP sequence number. */
+ pj_uint8_t rtp_seq_ts_set;
+ /**< Bitmask flags if initial RTP sequence
+ and/or timestamp for sender are set.
+ bit 0/LSB : sequence flag
+ bit 1 : timestamp flag */
int jb_init; /**< Jitter buffer init delay in msec.
(-1 for default). */
int jb_min_pre; /**< Jitter buffer minimum prefetch
diff --git a/pjmedia/src/pjmedia/rtp.c b/pjmedia/src/pjmedia/rtp.c
index 1f4de9e9..abcee1c7 100644
--- a/pjmedia/src/pjmedia/rtp.c
+++ b/pjmedia/src/pjmedia/rtp.c
@@ -84,6 +84,33 @@ PJ_DEF(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses,
return PJ_SUCCESS;
}
+PJ_DEF(pj_status_t) pjmedia_rtp_session_init2(
+ pjmedia_rtp_session *ses,
+ pjmedia_rtp_session_setting settings)
+{
+ pj_status_t status;
+ int pt = 0;
+ pj_uint32_t sender_ssrc = 0;
+
+ if (settings.flags & 1)
+ pt = settings.default_pt;
+ if (settings.flags & 2)
+ sender_ssrc = settings.sender_ssrc;
+
+ status = pjmedia_rtp_session_init(ses, pt, sender_ssrc);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (settings.flags & 4) {
+ ses->out_extseq = settings.seq;
+ ses->out_hdr.seq = pj_htons((pj_uint16_t)ses->out_extseq);
+ }
+ if (settings.flags & 8)
+ ses->out_hdr.ts = pj_htonl(settings.ts);
+
+ return PJ_SUCCESS;
+}
+
PJ_DEF(pj_status_t) pjmedia_rtp_encode_rtp( pjmedia_rtp_session *ses,
int pt, int m,
diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c
index ce87d048..83132167 100644
--- a/pjmedia/src/pjmedia/stream.c
+++ b/pjmedia/src/pjmedia/stream.c
@@ -872,6 +872,8 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
/* Update stat */
pjmedia_rtcp_tx_rtp(&stream->rtcp, frame_out.size);
+ stream->rtcp.stat.rtp_tx_last_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts);
+ stream->rtcp.stat.rtp_tx_last_seq = pj_ntohs(stream->enc->rtp.out_hdr.seq);
return PJ_SUCCESS;
}
@@ -1412,7 +1414,18 @@ static pj_status_t create_channel( pj_pool_t *pool,
/* Create RTP and RTCP sessions: */
- status = pjmedia_rtp_session_init(&channel->rtp, pt, param->ssrc);
+ if (param->rtp_seq_ts_set == 0) {
+ status = pjmedia_rtp_session_init(&channel->rtp, pt, param->ssrc);
+ } else {
+ pjmedia_rtp_session_setting settings;
+
+ settings.flags = (param->rtp_seq_ts_set << 2) | 3;
+ settings.default_pt = pt;
+ settings.sender_ssrc = param->ssrc;
+ settings.seq = param->rtp_seq;
+ settings.ts = param->rtp_ts;
+ status = pjmedia_rtp_session_init2(&channel->rtp, settings);
+ }
if (status != PJ_SUCCESS)
return status;
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index 5d7ff8f4..3839fa8f 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -66,6 +66,13 @@ typedef struct pjsua_call
pjmedia_session *session; /**< The media session. */
int audio_idx; /**< Index of m=audio in SDP. */
pj_uint32_t ssrc; /**< RTP SSRC */
+ pj_uint32_t rtp_tx_ts; /**< Initial RTP timestamp for sender. */
+ pj_uint16_t rtp_tx_seq;/**< Initial RTP sequence for sender. */
+ pj_uint8_t rtp_tx_seq_ts_set;
+ /**< Bitmask flags if initial RTP sequence
+ and/or timestamp for sender are set.
+ bit 0/LSB : sequence flag
+ bit 1 : timestamp flag */
int conf_slot; /**< Slot # in conference bridge. */
pjsip_evsub *xfer_sub; /**< Xfer server subscription, if this
call was triggered by xfer. */
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 114da50d..737cc017 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -105,6 +105,9 @@ static void reset_call(pjsua_call_id id)
call->session = NULL;
call->audio_idx = -1;
call->ssrc = pj_rand();
+ call->rtp_tx_seq = 0;
+ call->rtp_tx_ts = 0;
+ call->rtp_tx_seq_ts_set = 0;
call->xfer_sub = NULL;
call->last_code = (pjsip_status_code) 0;
call->conf_slot = PJSUA_INVALID_ID;
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 69314d30..6b0d2f63 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -1158,6 +1158,23 @@ static void stop_media_session(pjsua_call_id call_id)
}
if (call->session) {
+ pjmedia_rtcp_stat stat;
+
+ if (pjmedia_session_get_stream_stat(call->session,
+ call->audio_idx,
+ &stat) == PJ_SUCCESS)
+ {
+ /* Save RTP timestamp & sequence, so when media session is
+ * restarted, those values will be restored as the initial
+ * RTP timestamp & sequence of the new media session. So in
+ * the same call session, RTP timestamp and sequence are
+ * guaranteed to be contigue.
+ */
+ call->rtp_tx_seq_ts_set = 1 | (1 << 1);
+ call->rtp_tx_seq = stat.rtp_tx_last_seq;
+ call->rtp_tx_ts = stat.rtp_tx_last_ts;
+ }
+
if (pjsua_var.ua_cfg.cb.on_stream_destroyed) {
pjsua_var.ua_cfg.cb.on_stream_destroyed(call_id, call->session, 0);
}
@@ -1322,6 +1339,15 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
/* Set SSRC */
si->ssrc = call->ssrc;
+ /* Set RTP timestamp & sequence, normally these value are intialized
+ * automatically when stream session created, but for some cases (e.g:
+ * call reinvite, call update) timestamp and sequence need to be kept
+ * contigue.
+ */
+ si->rtp_ts = call->rtp_tx_ts;
+ si->rtp_seq = call->rtp_tx_seq;
+ si->rtp_seq_ts_set = call->rtp_tx_seq_ts_set;
+
/* Create session based on session info. */
status = pjmedia_session_create( pjsua_var.med_endpt, &sess_info,
&call->med_tp,