[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