[hydra-commits] hydra/media_rtp_pjmedia.git branch "master" updated.

Commits to the Hydra project code repositories hydra-commits at lists.digium.com
Sun Aug 15 17:53:15 CDT 2010


branch "master" has been updated
       via  dc10937f3410d7d3bd0506523ad0904c48b04a5a (commit)
       via  44d209b0b9e2705e204440c712860d8ca4f6dba2 (commit)
      from  445f160c9a64c9f94ad2a0b52f8e3d19213f0a58 (commit)

Summary of changes:
 src/MediaRTPpjmedia.cpp |    2 +-
 src/RTPSession.cpp      |   29 +++++++++++++++++++++++++++-
 src/RTPSession.h        |    2 +-
 src/RTPSource.cpp       |   48 +++++++++++++++++++++++++++++++++++++++++++++++
 src/RTPSource.h         |    3 +-
 5 files changed, 80 insertions(+), 4 deletions(-)


- Log -----------------------------------------------------------------
commit dc10937f3410d7d3bd0506523ad0904c48b04a5a
Author: Joshua Colp <jcolp at digium.com>
Date:   Sun Aug 15 20:05:01 2010 -0300

    Get the endpoint and transport actually created.

diff --git a/src/MediaRTPpjmedia.cpp b/src/MediaRTPpjmedia.cpp
index 229465c..26256d6 100644
--- a/src/MediaRTPpjmedia.cpp
+++ b/src/MediaRTPpjmedia.cpp
@@ -96,7 +96,7 @@ RTPMediaServiceImpl::RTPMediaServiceImpl(Ice::ObjectAdapterPtr adapter) : mAdapt
  */
 RTPSessionPrx RTPMediaServiceImpl::allocate(const FormatSeq& formats, const Ice::Current&)
 {
-	RTPSessionImplPtr session = new RTPSessionImpl(mAdapter, formats);
+	RTPSessionImplPtr session = new RTPSessionImpl(mAdapter, formats, &mCachingPool.factory);
 	return session->getProxy();
 }
 
diff --git a/src/RTPSession.cpp b/src/RTPSession.cpp
index c04312d..3e26884 100644
--- a/src/RTPSession.cpp
+++ b/src/RTPSession.cpp
@@ -34,6 +34,16 @@ using namespace Hydra::Media::V1;
 using namespace Hydra::Media::RTP::V1;
 
 /**
+ * Default value for where we should start allocating RTP and RTCP ports from.
+ */
+#define DEFAULT_RTP_PORT_MINIMUM 10000
+
+/**
+ * Default value for where we should stop allocating RTP and RTCP ports.
+ */
+#define DEFAULT_RTP_PORT_MAXIMUM 20000
+
+/**
  * Private implementation details for the RTPSessionImpl class.
  */
 class RTPSessionImplPriv
@@ -91,15 +101,27 @@ public:
 /**
  * Constructor for the RTPSessionImpl class.
  */
-RTPSessionImpl::RTPSessionImpl(Ice::ObjectAdapterPtr adapter, const FormatSeq& formats) : mImpl(new RTPSessionImplPriv(adapter, formats))
+RTPSessionImpl::RTPSessionImpl(Ice::ObjectAdapterPtr adapter, const FormatSeq& formats, pj_pool_factory* factory) : mImpl(new RTPSessionImplPriv(adapter, formats))
 {
 	/* Add ourselves to the ICE ASM so we can be used. */
 	mImpl->mProxy = RTPSessionPrx::uncheckedCast(adapter->addWithUUID(this));
 
 	/* Create an endpoint in pjmedia for our media. */
+	pj_status_t status = pjmedia_endpt_create(factory, NULL, 1, &mImpl->mEndpoint);
+
+	if (status != PJ_SUCCESS)
+	{
+		/* TODO: This is bad... we can't go on! */
+	}
 
 	/* Now create some transport we can use to actually send or receive the media. */
-	
+	for (int port = DEFAULT_RTP_PORT_MINIMUM; port < DEFAULT_RTP_PORT_MAXIMUM; port += 2)
+	{
+		if ((status = pjmedia_transport_udp_create2(mImpl->mEndpoint, "RTP", NULL, port, 0, &mImpl->mTransport)) == PJ_SUCCESS)
+		{
+			break;
+		}
+	}
 
 	/* First up for our own stuff is... a source! Media needs to come from somewhere, you know. */
 	mImpl->mStreamSource = new StreamSourceRTPImpl(this);
@@ -115,6 +137,10 @@ RTPSessionImpl::RTPSessionImpl(Ice::ObjectAdapterPtr adapter, const FormatSeq& f
  */
 RTPSessionImplPriv::~RTPSessionImplPriv()
 {
+	/* Drop the source and sink from the ASM */
+	mAdapter->remove(mStreamSourceProxy->ice_getIdentity());
+	mAdapter->remove(mStreamSinkProxy->ice_getIdentity());
+
 	/* Discontinue the media transport. */
 	pjmedia_transport_close(mTransport);
 
diff --git a/src/RTPSession.h b/src/RTPSession.h
index 43c5d99..620b2a5 100644
--- a/src/RTPSession.h
+++ b/src/RTPSession.h
@@ -31,7 +31,7 @@ class RTPSessionImplPriv;
 class RTPSessionImpl : public Hydra::Media::RTP::V1::RTPSession
 {
 public:
-	RTPSessionImpl(Ice::ObjectAdapterPtr, const Hydra::Media::V1::FormatSeq&);
+	RTPSessionImpl(Ice::ObjectAdapterPtr, const Hydra::Media::V1::FormatSeq&, pj_pool_factory*);
 	Hydra::Media::V1::StreamSourceSeq getSources(const Ice::Current&);
 	Hydra::Media::V1::StreamSinkSeq getSinks(const Ice::Current&);
 	std::string getId(const Ice::Current&);

commit 44d209b0b9e2705e204440c712860d8ca4f6dba2
Author: Joshua Colp <jcolp at digium.com>
Date:   Sun Aug 15 19:43:41 2010 -0300

    Get the transport attached and reception of RTP packets going. Frames don't yet get written to the sink, but one step at a time.

diff --git a/src/RTPSession.cpp b/src/RTPSession.cpp
index 82fc159..c04312d 100644
--- a/src/RTPSession.cpp
+++ b/src/RTPSession.cpp
@@ -99,6 +99,7 @@ RTPSessionImpl::RTPSessionImpl(Ice::ObjectAdapterPtr adapter, const FormatSeq& f
 	/* Create an endpoint in pjmedia for our media. */
 
 	/* Now create some transport we can use to actually send or receive the media. */
+	
 
 	/* First up for our own stuff is... a source! Media needs to come from somewhere, you know. */
 	mImpl->mStreamSource = new StreamSourceRTPImpl(this);
diff --git a/src/RTPSource.cpp b/src/RTPSource.cpp
index 60e9ba0..e63201b 100644
--- a/src/RTPSource.cpp
+++ b/src/RTPSource.cpp
@@ -135,8 +135,56 @@ Ice::Int StreamSourceRTPImpl::getLocalPort(const Ice::Current&)
 }
 
 /**
+ * Function which is called when RTP media is received.
+ */
+static void receiveRTP(void *userdata, void *packet, pj_ssize_t size)
+{
+	StreamSourceRTPImpl* source = static_cast<StreamSourceRTPImpl*>(userdata);
+
+	/* Ensure that no errors occurred when reading this packet in */
+	if (size < 0)
+	{
+		/* TODO: Determine what we should do, spit out an error? */
+		return;
+	}
+
+	const pjmedia_rtp_hdr* header;
+	const void* payload;
+	unsigned int payload_size;
+
+	pj_status_t status = pjmedia_rtp_decode_rtp(&source->mImpl->mIncomingSession, packet, size, &header, &payload, &payload_size);
+
+	if (status != PJ_SUCCESS)
+	{
+		/* TODO: Somehow we failed to parse the RTP header, nothing we can really do... */
+		return;
+	}
+
+	/* Here is where we need to construct a frame and write it to the sink */
+
+	/* Now that all is said and done update the internal RTP stack state */
+	pjmedia_rtp_session_update(&source->mImpl->mIncomingSession, header, NULL);
+}
+
+/**
  * API call which sets up our pjmedia transport and allows media to be sent and received.
  */
 void StreamSourceRTPImpl::setRemoteDetails(std::string address, int port)
 {
+	pj_sockaddr_in sin;
+
+	/* This feels so dirty but convert from our std::string to a pj_str, since their API requires it. */
+	pj_str_t tmpAddress;
+	pj_strset(&tmpAddress, (char*)address.c_str(), address.size());
+
+	/* Now for the next trick - convert into a pj_sockaddr_in so we can pass it to pjmedia_transport_attach */
+	pj_sockaddr_in_init(&sin, &tmpAddress, port);
+
+	/* All ready... actually do it! */
+	pj_status_t status = pjmedia_transport_attach(mImpl->mSession->getTransport(), this, &sin, NULL, sizeof(pj_sockaddr_in), &receiveRTP, NULL);
+
+	if (status != PJ_SUCCESS)
+	{
+		/* TODO: Decide what to do if this occurs, do we need an exception? */
+	}
 }
diff --git a/src/RTPSource.h b/src/RTPSource.h
index 5d372c3..10416f9 100644
--- a/src/RTPSource.h
+++ b/src/RTPSource.h
@@ -40,9 +40,10 @@ public:
 	std::string getLocalAddress(const Ice::Current&);
 	Ice::Int getLocalPort(const Ice::Current&);
 	void setRemoteDetails(std::string address, int port);
-private:
+
 	/**
 	 * Private implementation data for StreamSourceRTPImpl.
+	 * Note: This is public on purpose so that our RTP callback can access it.
 	 */
 	boost::shared_ptr<StreamSourceRTPImplPriv> mImpl;
 };

-----------------------------------------------------------------------


-- 
hydra/media_rtp_pjmedia.git




More information about the asterisk-scf-commits mailing list