summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pjmedia/build/pjmedia.dsp8
-rw-r--r--pjmedia/include/pjmedia/rtp_port.h53
-rw-r--r--pjmedia/src/pjmedia/rtp_port.c234
-rw-r--r--pjmedia/src/pjmedia/stream.c31
4 files changed, 29 insertions, 297 deletions
diff --git a/pjmedia/build/pjmedia.dsp b/pjmedia/build/pjmedia.dsp
index f754702a..894107d7 100644
--- a/pjmedia/build/pjmedia.dsp
+++ b/pjmedia/build/pjmedia.dsp
@@ -145,10 +145,6 @@ SOURCE=..\src\pjmedia\rtp.c
# End Source File
# Begin Source File
-SOURCE=..\src\pjmedia\rtp_port.c
-# End Source File
-# Begin Source File
-
SOURCE=..\src\pjmedia\sdp.c
# End Source File
# Begin Source File
@@ -233,10 +229,6 @@ SOURCE=..\include\pjmedia\rtp.h
# End Source File
# Begin Source File
-SOURCE=..\include\pjmedia\rtp_port.h
-# End Source File
-# Begin Source File
-
SOURCE=..\include\pjmedia\sdp.h
# End Source File
# Begin Source File
diff --git a/pjmedia/include/pjmedia/rtp_port.h b/pjmedia/include/pjmedia/rtp_port.h
deleted file mode 100644
index 7bb93cb2..00000000
--- a/pjmedia/include/pjmedia/rtp_port.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __PJMEDIA_RTP_PORT_H__
-#define __PJMEDIA_RTP_PORT_H__
-
-
-/**
- * @file rtp_port.h
- * @brief RTP media port.
- */
-#include <pjmedia/port.h>
-
-
-PJ_BEGIN_DECL
-
-
-/**
- * Create RTP port.
- */
-PJ_DECL(pj_status_t) pjmedia_rtp_port_create(pj_pool_t *pool,
- pjmedia_sock_info *sock_info,
- pjmedia_port **p_port);
-
-
-/**
- * Set RTP destination info.
- */
-PJ_DECL(pj_status_t) pjmedia_rtp_port_configure(pjmedia_port *rtp,
- const pj_sockaddr_in *rem_rtp,
- const pj_sockaddr_in *rem_rtcp);
-
-
-
-PJ_END_DECL
-
-
-#endif /* __PJMEDIA_RTP_PORT_H__ */
diff --git a/pjmedia/src/pjmedia/rtp_port.c b/pjmedia/src/pjmedia/rtp_port.c
deleted file mode 100644
index 26672662..00000000
--- a/pjmedia/src/pjmedia/rtp_port.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <pjmedia/rtp_port.h>
-#include <pjmedia/errno.h>
-#include <pjmedia/rtp.h>
-#include <pjmedia/rtcp.h>
-#include <pj/assert.h>
-#include <pj/pool.h>
-#include <pj/sock_select.h>
-#include <pj/string.h>
-
-
-#define RTP_PORT_SIGNATURE ('R'<<2 | 'T'<<1 | 'P')
-
-struct rtp_port
-{
- pjmedia_port base;
- pjmedia_sock_info sock_info;
- pj_sockaddr_in rem_rtp_addr;
- pj_sockaddr_in rem_rctp_addr;
- pjmedia_rtp_session tx_session;
- pjmedia_rtp_session rx_session;
- pj_rtcp_session rtcp;
- char tx_buf[1500];
- char rx_buf[1500];
-};
-
-
-static pj_status_t rtp_on_upstream_connect(pj_pool_t *pool,
- pjmedia_port *this_port,
- pjmedia_port *upstream);
-static pj_status_t rtp_put_frame( pjmedia_port *this_port,
- const pjmedia_frame *frame);
-static pj_status_t rtp_get_frame( pjmedia_port *this_port,
- pjmedia_frame *frame);
-static pj_status_t rtp_on_destroy( pjmedia_port *this_port );
-
-
-PJ_DEF(pj_status_t) pjmedia_rtp_port_create( pj_pool_t *pool,
- pjmedia_sock_info *sock_info,
- pjmedia_port **p_port)
-{
- struct rtp_port *rtp;
-
- PJ_ASSERT_RETURN(pool && sock_info && p_port,
- PJ_EINVAL);
-
-
- rtp = pj_pool_zalloc(pool, sizeof(struct rtp_port));
- rtp->base.info.name = pj_str("rtp");
- rtp->base.info.signature = RTP_PORT_SIGNATURE;
- rtp->base.info.type = PJMEDIA_TYPE_NONE;
- rtp->base.info.has_info = PJ_FALSE;
- rtp->base.info.need_info = PJ_TRUE;
-
- rtp->base.on_upstream_connect = &rtp_on_upstream_connect;
- rtp->base.put_frame = &rtp_put_frame;
- rtp->base.get_frame = &rtp_get_frame;
- rtp->base.on_destroy = &rtp_on_destroy;
-
- pj_memcpy(&rtp->sock_info, sock_info, sizeof(pjmedia_sock_info));
-
- return PJ_SUCCESS;
-}
-
-
-PJ_DEF(pj_status_t) pjmedia_rtp_port_configure( pjmedia_port *rtp,
- const pj_sockaddr_in *rem_rtp,
- const pj_sockaddr_in *rem_rtcp)
-{
- struct rtp_port *rtp_port = (struct rtp_port *)rtp;
-
- PJ_ASSERT_RETURN(rtp, PJ_EINVAL);
-
- if (rem_rtp) {
- pj_memcpy(&rtp_port->rem_rtp_addr, rem_rtp, sizeof(pj_sockaddr_in));
- }
- if (rem_rtcp) {
- pj_memcpy(&rtp_port->rem_rctp_addr, rem_rtcp, sizeof(pj_sockaddr_in));
- }
-
- return PJ_SUCCESS;
-}
-
-
-static pj_status_t rtp_on_upstream_connect(pj_pool_t *pool,
- pjmedia_port *this_port,
- pjmedia_port *upstream)
-{
- struct rtp_port *rtp_port = (struct rtp_port *)this_port;
-
- rtp_port->base.info.type = upstream->info.type;
- rtp_port->base.info.pt = upstream->info.pt;
- pj_strdup(pool, &rtp_port->base.info.encoding_name,
- &upstream->info.encoding_name);
- rtp_port->base.info.sample_rate = upstream->info.sample_rate;
- rtp_port->base.info.bits_per_sample = upstream->info.bits_per_sample;
- rtp_port->base.info.samples_per_frame = upstream->info.samples_per_frame;
- rtp_port->base.info.bytes_per_frame = upstream->info.bytes_per_frame;
-
- rtp_port->base.info.has_info = PJ_TRUE;
-
- pjmedia_rtp_session_init(&rtp_port->tx_session, upstream->info.pt, 10);
- pjmedia_rtp_session_init(&rtp_port->rx_session, upstream->info.pt, 10);
- pj_rtcp_init(&rtp_port->rtcp, 10);
-
- return PJ_SUCCESS;
-}
-
-static pj_status_t rtp_put_frame( pjmedia_port *this_port,
- const pjmedia_frame *frame)
-{
- struct rtp_port *rtp_port = (struct rtp_port *)this_port;
- void *rtphdr;
- int rtphdrlen;
- pj_ssize_t sent;
- pj_status_t status;
-
- if (!rtp_port->base.info.has_info)
- return PJMEDIA_RTP_ENOCONFIG;
-
- if (rtp_port->rem_rtp_addr.sin_family != PJ_AF_INET)
- return PJMEDIA_RTP_EBADDEST;
-
- status = pjmedia_rtp_encode_rtp(&rtp_port->tx_session,
- rtp_port->base.info.pt,
- 0, frame->size,
- (frame->size / rtp_port->base.info.bytes_per_frame),
- &rtphdr, &rtphdrlen);
- if (status != PJ_SUCCESS)
- return status;
-
- if (rtphdrlen != sizeof(pjmedia_rtp_hdr))
- return PJMEDIA_RTP_EINPKT;
-
-
- /* Scatter send in PJLIB will be nice here..! */
- pj_memcpy(rtp_port->tx_buf, rtphdr, sizeof(pjmedia_rtp_hdr));
- pj_memcpy(rtp_port->tx_buf+sizeof(pjmedia_rtp_hdr), frame->buf, frame->size);
-
- sent = sizeof(pjmedia_rtp_hdr) + frame->size;
- status = pj_sock_sendto( rtp_port->sock_info.rtp_sock,
- rtp_port->tx_buf, &sent, 0,
- &rtp_port->rem_rtp_addr,
- sizeof(rtp_port->rem_rtp_addr));
-
- return status;
-}
-
-
-static pj_status_t rtp_get_frame( pjmedia_port *this_port,
- pjmedia_frame *frame)
-{
- struct rtp_port *rtp_port = (struct rtp_port *)this_port;
- pj_fd_set_t fds;
- pj_time_val timeout = { 0, 0};
- pj_ssize_t pktlen;
- const pjmedia_rtp_hdr *hdr;
- const void *payload;
- unsigned payloadlen;
- pj_status_t status;
-
- PJ_FD_ZERO(&fds);
- PJ_FD_SET(rtp_port->sock_info.rtp_sock, &fds);
-
- /* Check for incoming packet. */
- status = pj_sock_select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
- if (status <= 0)
- goto on_error;
-
- /* Receive packet. */
- pktlen = sizeof(rtp_port->rx_buf);
- status = pj_sock_recv(rtp_port->sock_info.rtp_sock,
- rtp_port->rx_buf, &pktlen, 0);
- if (pktlen < 1 || status != PJ_SUCCESS)
- goto on_error;
-
-
- /* Update RTP and RTCP session. */
- status = pjmedia_rtp_decode_rtp(&rtp_port->rx_session,
- rtp_port->rx_buf, pktlen,
- &hdr, &payload, &payloadlen);
- if (status != PJ_SUCCESS)
- goto on_error;
-
-
- status = pjmedia_rtp_session_update(&rtp_port->rx_session, hdr);
- if (status != 0 &&
- status != PJMEDIA_RTP_ESESSPROBATION &&
- status != PJMEDIA_RTP_ESESSRESTART)
- {
- goto on_error;
- }
- pj_rtcp_rx_rtp(&rtp_port->rtcp, pj_ntohs(hdr->seq), pj_ntohl(hdr->ts));
-
- /* Copy */
- if (frame->size > payloadlen) frame->size = payloadlen;
- pj_memcpy(frame->buf, payload, frame->size);
- frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
- frame->timestamp.u64 = pj_ntohl(hdr->ts);
-
- return PJ_SUCCESS;
-
-
-on_error:
- frame->type = PJMEDIA_FRAME_TYPE_NONE;
- frame->size = 0;
- return PJ_SUCCESS;
-}
-
-
-static pj_status_t rtp_on_destroy( pjmedia_port *this_port )
-{
- PJ_UNUSED_ARG(this_port);
- return PJ_SUCCESS;
-}
-
-
diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c
index 5c9268dd..8b41a948 100644
--- a/pjmedia/src/pjmedia/stream.c
+++ b/pjmedia/src/pjmedia/stream.c
@@ -41,6 +41,7 @@
#define PJMEDIA_MAX_BUFFER_SIZE_MS 2000
#define PJMEDIA_MAX_MTU 1500
#define PJMEDIA_DTMF_DURATION 1600 /* in timestamp */
+#define PJMEDIA_RTP_NAT_PROBATION_CNT 10
/**
@@ -97,6 +98,9 @@ struct pjmedia_stream
pj_sockaddr_in rem_rtp_addr; /**< Remote RTP address. */
pj_sockaddr_in rem_rtcp_addr; /**< Remote RTCP address. */
+ pj_sockaddr_in rem_src_rtp; /**< addr of src pkt from remote*/
+ unsigned rem_src_cnt; /**< if different, # of pkt rcv */
+
pj_rtcp_session rtcp; /**< RTCP for incoming RTP. */
pj_bool_t quit_flag; /**< To signal thread exit. */
@@ -450,6 +454,7 @@ static int PJ_THREAD_FUNC jitter_buffer_thread (void*arg)
const pjmedia_rtp_hdr *hdr;
const void *payload;
unsigned payloadlen;
+ int addrlen;
int status;
/* Wait for packet. */
@@ -473,8 +478,10 @@ static int PJ_THREAD_FUNC jitter_buffer_thread (void*arg)
/* Get packet from socket. */
len = channel->in_pkt_size;
- status = pj_sock_recv(stream->skinfo.rtp_sock,
- channel->in_pkt, &len, 0);
+ addrlen = sizeof(stream->rem_src_rtp);
+ status = pj_sock_recvfrom(stream->skinfo.rtp_sock,
+ channel->in_pkt, &len, 0,
+ &stream->rem_src_rtp, &addrlen);
if (len < 1 || status != PJ_SUCCESS) {
if (pj_get_netos_error() == PJ_STATUS_FROM_OS(OSERR_ECONNRESET)) {
/* On Win2K SP2 (or above) and WinXP, recv() will get
@@ -521,6 +528,26 @@ static int PJ_THREAD_FUNC jitter_buffer_thread (void*arg)
stream->stat.dec.pkt++;
stream->stat.dec.bytes += len;
+ /* See if source address of RTP packet is different than the
+ * configured address.
+ */
+ if ((stream->rem_rtp_addr.sin_addr.s_addr !=
+ stream->rem_src_rtp.sin_addr.s_addr) ||
+ (stream->rem_rtp_addr.sin_port != stream->rem_src_rtp.sin_port))
+ {
+ stream->rem_src_cnt++;
+
+ if (stream->rem_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) {
+
+ stream->rem_rtp_addr = stream->rem_src_rtp;
+ stream->rem_src_cnt = 0;
+
+ PJ_LOG(4,(THIS_FILE,"Remote RTP address switched to %s:%d",
+ pj_inet_ntoa(stream->rem_src_rtp.sin_addr),
+ pj_ntohs(stream->rem_src_rtp.sin_port)));
+ }
+ }
+
/* Put to jitter buffer. */
pj_mutex_lock( stream->jb_mutex );
status = pjmedia_jbuf_put_frame(stream->jb, payload, payloadlen, pj_ntohs(hdr->seq));