[asterisk-scf-commits] asterisk-scf/integration/media_rtp_pjmedia.git branch "nat-traversal" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Thu Apr 28 13:40:19 CDT 2011


branch "nat-traversal" has been updated
       via  d129982f703ddde8692228e71454c6cc94b443d9 (commit)
       via  d4acee2e3f78c5dfca0a72a90c873d0ba2f106d3 (commit)
       via  ddc3a6e767485cd4b5a3ca15ad0f3613826e3bc7 (commit)
       via  fb3751f703ad0d1fb4b3ba17d0f3db484fdeca53 (commit)
       via  37b6b32b5336299fac3895f36093d74d97c77a80 (commit)
       via  6f40364bd44771f7cb097767d88ca3ef0190a345 (commit)
       via  8f8692cd47c17cbfac081f3c69ab3f270acddcc6 (commit)
       via  6359f9d3d8edea8e3b27dfa59bc81deb1a9d2fc0 (commit)
       via  d49f78113d8222ec5b2a7a530332ec78962c9031 (commit)
       via  85553b42ab3952da5bc79b551aa1f1010b0c6f85 (commit)
       via  70bd6106cdd277a8994b27d62c836deb2c83ed81 (commit)
       via  7e3d172b518669dff018e3177ceb2b13cf80a3b8 (commit)
       via  bd6452ec09f440b872d99b2b56b818d0b816ff78 (commit)
       via  c62a171fb8baea2a25b3fc817d96aa186e98db32 (commit)
      from  d173b7aa471e7ae3deb40dee93868170b8d6dda4 (commit)

Summary of changes:
 CMakeLists.txt                                     |    6 +-
 config/CMakeLists.txt                              |    9 --
 ...t_component.config.in => test_component.config} |    9 +-
 config/test_media_rtp_pjmedia.conf                 |    2 +-
 src/MediaRTPpjmedia.cpp                            |    6 +-
 src/RTPSession.cpp                                 |    2 +-
 src/RTPSession.h                                   |    2 +-
 src/RTPSink.cpp                                    |    4 +-
 src/RTPSource.cpp                                  |   18 ++++-
 src/RTPSource.h                                    |    2 +-
 src/RtpStateReplicatorApp.cpp                      |    4 +-
 src/RtpStateReplicatorListener.cpp                 |   30 ++++----
 test/CMakeLists.txt                                |    2 +-
 test/TestRTPpjmedia.cpp                            |   78 +++++++++++---------
 14 files changed, 92 insertions(+), 82 deletions(-)
 delete mode 100644 config/CMakeLists.txt
 rename config/{test_component.config.in => test_component.config} (80%)


- Log -----------------------------------------------------------------
commit d129982f703ddde8692228e71454c6cc94b443d9
Merge: d4acee2 d173b7a
Author: Brent Eagles <beagles at digium.com>
Date:   Thu Apr 28 13:11:32 2011 -0230

    Merge branch 'nat-traversal' of ssh://git.asterisk.org/asterisk-scf/integration/media_rtp_pjmedia into nat-traversal


commit d4acee2e3f78c5dfca0a72a90c873d0ba2f106d3
Author: Brent Eagles <beagles at digium.com>
Date:   Mon Apr 25 13:23:18 2011 -0230

    Some in-progress NAT traversal changes.

diff --git a/src/RTPICESession.cpp b/src/RTPICESession.cpp
new file mode 100644
index 0000000..1d75ede
--- /dev/null
+++ b/src/RTPICESession.cpp
@@ -0,0 +1,540 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include <pjlib.h>
+#include <Ice/Ice.h>
+#include <IceUtil/UUID.h>
+
+#include <pjmedia.h>
+#include <pjnath.h>
+
+#include <AsteriskSCF/Media/MediaIf.h>
+#include <AsteriskSCF/Media/RTP/MediaRTPIf.h>
+#include <AsteriskSCF/System/Component/ReplicaIf.h>
+#include <AsteriskSCF/System/ExceptionsIf.h>
+#include <AsteriskSCF/SmartProxy.h>
+
+#include "RtpStateReplicationIf.h"
+
+#include "RTPSource.h"
+#include "RTPSink.h"
+
+#include "ServiceConfig.h"
+
+#include <boost/bind.hpp>
+
+using namespace std;
+using namespace AsteriskSCF::Media::V1;
+using namespace AsteriskSCF::Media::RTP::V1;
+
+namespace ICEMediaSession
+{
+static bool success(pj_status_t r)
+{
+    return r == PJ_SUCCESS;
+}
+
+static bool fail(pj_status_t r)
+{
+    return !success(r);
+}
+
+typedef AsteriskSCF::SmartProxy::SmartProxy<RtpStateReplicatorPrx> StateReplicatorPrx;
+
+class NATModule : public IceUtil::Shared
+{
+public:
+    NATModule(const PjlibEnvironmentPtr& environ, const Ice::PropertiesPtr& props, const Logger& logger)
+    {
+        std::string stunServerProperty = props->getProperty("Media.STUN.Server");
+        //
+        // XXX:
+        // This actually isn't necessarily an error, the STUN server can be determined from
+        // DNS records. Let's leave it for now.
+        //
+        //
+        if (stunServerProperty.empty())
+        {
+            throw InternalInitializationException("No STUN server configured");
+        }
+        Ice::Int portProperty = props->getPropertyAsIntWithDefault("Media.STUN.Port", PJ_STUN_PORT);
+        if (portProperty > UINT_MAX)
+        {
+            logger(Warning) << "Property `Media.STUN.Port' is out of range for IP port numbers, defaulting to "
+                            << PJ_STUN_PORT;
+            portProperty = PJ_STUN_PORT;
+        }
+        pj_ice_strans_cfg_default(&mICECfg);
+        pj_stun_config_init(&mICECfg.stun_cfg, environ->getPoolFactory(), 0
+            pjmedia_endpoint_get_ioqueue(environ->getMediaEndpoint()), 0);
+        pj_status_t result = pj_timer_heap_create(environ->getPool(), 
+            props->getPropertyAsIntWithDefault("Media.PJMedia.TimerHeap.Size", 1000), &mICECfg.stun_cfg.timer_heap);
+        if (fail(result))
+        {
+            throw InternalInitializationException("Unable to initialize timer heap.");
+        }
+        pj_strdup2(environ->getPool(), mICECfg.stun.server, stunServerProperty.c_str());
+        mICECfg.stun.port = portProperty;
+
+        mICECfg.stun.max_host_cands = props->getPropertyAsIntWithDefault("Media.ICE.MaxCandidates",  2);
+        if (props->getPropertyAsIntWithDefault("Media.TURN.Enable", 0) > 0)
+        {
+            string turnServer = props->getProperty("Media.TURN.Server.Hostname");
+            //
+            // XXX: verify default TURN server port number.
+            //
+            Ice::Int turnPort = props->getPropertyAsIntWithDefault("Media.TURN.Server.Port", 3479);
+            pj_strdup2(environ->getPool(), mICE.turn.server, turnServer.c_str());
+            mICE.turn.server.port = turnPort;
+
+            //
+            // TODO: TURN QoS settings.
+            // 
+        }
+        //
+        // TODO: QoS.
+        //
+    }
+
+    void start()
+    {
+        //
+        // commence resolving STUN server, etc.
+        //
+    }
+
+protected:
+    ~NATModule()
+    {
+        pj_time_heap_destroy(&mICECfg.timer_heap);
+    }
+
+private:
+    pj_ice_strans_cfg mICECfg;
+
+};
+
+typedef IceUtil::Handle<NATModule> NATModulePtr;
+
+class PjLibEnvironment : public IceUtil::Shared
+{
+public:
+    PjLibEnvironment(pj_pool_factory* poolFactory, const Ice::PropertiesPtr& props, const Logger& logger) :
+        mPoolFactory(poolFactory),
+        mProperties(props),
+        mMediaEndpoint(0),
+        mPool(0),
+        mLogger(logger)
+    {
+        pj_status_t result = pjmedia_endpt_create(mPjLib->getPoolFactory(), 0, 1, &mEndpoint);
+        if (fail(result))
+        {
+            throw InternalInitializationException("Unable to create PJMEDIA endpoint.");
+        }
+    }
+    
+    pj_pool_factory* getPoolFactory() const
+    {
+        boost::shared_lock<boost::shared_mutex> lock(mLock);
+        return mPoolFactory;
+    }
+
+    pjmedia_endpoint* getMediaEndpoint() const
+    {
+        boost::shared_lock<boost::shared_mutex> lock(mLock);
+        return mMediaEndpoint;
+    }
+
+    pj_pool_t* getPool() const
+    {
+        boost::unique_lock<boost::shared_mutex> lock(mLock);
+        if (!mPool)
+        {
+            pj_status_t result = pjmedia_endpt_create_pool(mMediaEndpoint, "SESSPOOL", 1024, 512);
+            if (fail(result))
+            {
+                throw InternalInitializationException("Unable to initialize pool.");
+            }
+        }
+        return mPool;
+    }
+
+    NATModulePtr getNATModule()
+    {
+        boost::unique_lock<boost::shared_mutex> lock(mLock);
+        if (!mNATModule)
+        {
+            mNATModule = new NATModule(this, mProperties, mLogger);
+        }
+    }
+
+    void destroy()
+    {
+        boost::unique_lock<boost::shared_mutex> lock(mLock);
+        mNATModule = 0;
+    }
+
+private:
+    mutable boost::shared_mutex mLock;
+    pj_pool_factory* mPoolFactory;
+    Ice::PropertiesPtr mProperties;
+    pjmedia_endpoint* mMediaEndpoint;
+    NATModulePtr mNATModule;
+    pj_pool_t* mPool;
+    Logger mLogger;
+};
+typedef IceUtil::Handle<PjLibEnvironment> PjLibEnvironmentPtr;
+
+class RTPSessionImpl : public RTPSession
+{
+public:
+
+    //
+    // RTPSessionImpl uses a two-stage initialization to reduce duplication
+    // amongst constructor versions and avoid exception prone calls in
+    // the constructor itself.
+    //
+    RTPSessionImpl(const FormatSeq& formats, const PjLibEnvironmentPtr& pjLib,
+            const ReplicatorPtr& replicaService, const StateReplicatorPrx& replicator);
+
+    void initialize();
+
+    //
+    // Slice to C++ mapping.
+    //
+
+    //
+    // Session
+    //
+    StreamSourceSeq getSources(const Ice::Current& current);
+    StreamSinkSeq getSinks(const Ice::Current& current);
+    std::string getId(const Ice::Current& current);
+    
+    //
+    // RTPSession.
+    //
+    void associatePayLoads(const PayLoadMap& mappings, const Ice::Current& current);
+    void useRTCP(bool enable, const Ice::Current& current);
+    RTCPSessionPrx getRTCPSession(const Ice::Current& current);
+    void release(const Ice::Current& current);
+
+    //
+    // Internal methods.
+    //
+private:
+    FormatSeq mFormats;
+    PjLibEnvironmentPtr mPjLib;
+    ReplicatorPtr mReplicaControl;
+    StateReplicatorPrx mReplicator;
+
+    //
+    // TODO: Should the endpoint belong to a different object. Could a single endpoint
+    // have multiple transports?
+    //
+    pjmedia_endpt* mEndpoint;
+    pjmedia_transport* mTransport;
+    
+};
+
+typedef IceUtil::Handle<RTPSessionImpl> RTPSessionImplPtr;
+
+class SinkImpl : public StreamSinkRTP
+{
+public:
+
+    SinkImpl();
+
+    //
+    // Slice to C++ mapping.
+    //
+
+    //
+    // StreamSink
+    //
+    void write(const FrameSeq& frames, const Ice::Current& current);
+    void setSource(const StreamSourcePrx& source, const Ice::Current& current);
+    StreamSourcePrx getSource(const Ice::Current& current);
+    FormatSeq getFormats(const Ice::Current& current);
+    std::string getId(const Ice::Current& current);
+
+    //
+    // StreamSinkRTP
+    //
+    void setRemoteDetails(const std::string& address, int port, const Ice::Current& current);
+    std::string getRemoteAddress(const Ice::Current& current);
+    int getRemotePort(const Ice::Current& current);
+
+    //
+    // Internal methods.
+    //
+    void destroy();
+};
+
+class SourceImpl : public StreamSourceRTP
+{
+public:
+    SourceImpl();
+
+    //
+    // Slice to C++ mapping.
+    //
+
+    //
+    // StreamSource
+    //
+    void setSink(const StreamSinkPrx& destination, const Ice::Current& current);
+    StreamSinkPrx getSink(const Ice::Current& current);
+    FormatSeq getFormats(const Ice::Current& current);
+    std::string getId( const Ice::Current& current);
+    void requestFormat(const FormatPtr& newFormat, const Ice::Current& current);
+
+    //
+    // Internal methods.
+    //
+    void destroy();
+};
+
+/**
+ *
+ * Base class to allow some polymorphic behavior on different pjmedia based transports.
+ *
+ **/ 
+class PJMediaTransport : public IceUtil::Shared
+{
+public:
+    
+    pjmedia_transport* getTransport()
+    {
+        boost::shared_lock<boost::shared_mutex> lock(mLock);
+        return mTransport;
+    }
+
+    Ice::Int getPort()
+    {
+        boost::shared_lock<boost::shared_mutex> lock(mLock);
+        return mPort;
+
+    void destroy()
+    {
+        boost::unique_locK<boost::shared_mutex> lock(mLock);
+        pjmedia_transport_close(mTransport);
+        mPort = 0;
+        mTransport = 0;
+    }
+
+protected:
+    boost::shared_mutex mLock;
+    pjmedia_transport* mTransport;
+    Ice::Int mPort;
+
+    PJMediaTransport(pjmedia_transport* t, const Ice::Int p) :
+        mTransport(t),
+        mPort(p)
+    {
+    }
+};
+
+class ICETransport : public PJMediaTransport
+{
+    //
+    // Hidden and unimplemented.
+    //
+    ICETransport(const ICETransport&);
+    void operator=(const ICETransport&);
+    
+public:
+    static IceUtil::Handle<ICETransport> create(const PjLibEnvironmentPtr& pjlib)
+    {
+        pjmedia_ice_create(mPjLib->getMediaEndpoint(), "ASCF_ICE_MEDIA", 10, 0, &ICECallbackAdapter::onIceComplete,
+                &mTransport);
+    }
+};
+typedef IceUtil::Handle<ICETransport> ICETransportPtr;
+
+class UDPTransport : public PJMediaTransport
+{
+    //
+    // Hidden and unimplemented.
+    //
+    UDPTransport(const UDPTransport&);
+    void operator=(const UDPTransport&);
+    
+public:
+    //
+    // Replicant version.
+    //
+    static IceUtil::Handle<UDPTransport> create(const PjLibEnvironmentPtr& pjlib, Ice::Int port)
+    {
+        pjmedia_transport* transport;
+        pj_status_t result = pjmedia_transport_udp_create2(pjlib->getMediaEndpoint(), "RTP", 0, port, transport);
+        if (fail(result))
+        {
+            throw InternalInitializationException("Unable to initialize UDP media transport on "
+                    "replicant, port conflict!");
+        }
+        return new UDPTransport(transport, port);
+    }
+    
+    //
+    // Primary version.
+    //
+    static IceUtil::Handle<UDPTransport> create(const PjLibEnvironmentPtr& pjlib, Ice::Int port)
+    {
+        const Ice::Int minPort =
+            properties->getPropertyAsIntWithDefault("AsteriskSCF.Media.Transport.UDPTransport.MinPort",
+                DefaultRTPPortMinimum);
+        const Ice::Int maxPort =
+            properties->getPropertyAsIntWithDefault("AsteriskSCF.Media.Transport.UDPTransport.MaxPort",
+                DefaultRTPPortMaximum);
+
+        //
+        // Now create some transport we can use to actually send or receive the media. The candidate ports increment by
+        // two to allow "room" for both a control and a data port.
+        //
+        for (Ice::Int port = minPort; port < maxPort && port <= USHRT_MAX ; port +=2)
+        {
+            pjmedia_transport* transport;
+            pj_result_t result = pjmedia_transport_udp_create2(pjlib->getMediaEndpoint(), "RTP", 0, port, 0, &transport);
+            if (success(result))
+            {
+                return new UDPTransport(transport, port);
+            }
+        }
+        throw InternalInitializationException("Unable to initialize UDP media transport");
+    }
+
+private:
+    UDPTransport(pjmedia_transport* t, const Ice::Int port) :
+        PJMediaTransport(t, port)
+    {
+    }
+};
+typedef IceUtil::Handle<UDPTransport> UDPTransportPtr;
+
+pjmedia_transport* PJMediaTransport::getTransport()
+{
+    boost::shared_lock<boost::shared_mutex> lock(mLock);
+    return mTransport;
+}
+
+class ICECallbackAdapter
+{
+public:
+    typedef std::map<pjmedia_transport*, RTPSessionImplPtr> TransportMap;
+
+    static void addEntry(pjmedia_transport* transport, const RTPSessionImplPtr& callback)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(mLock);
+        TransportMap::iterator i = mTransportMap.find(transport);
+        if (i != mTransportMap.end())
+        {
+            mTransportMap.insert(make_pair(transport, callback));
+        }
+    }
+
+    static void onICEComplete(pjmedia_transport* transport, pj_ice_strans_op operation, pj_status_t status)
+    {
+        switch (operation)
+        {
+            //
+            // TODO: Fill out.
+            //
+            case PJ_ICE_STRANS_OP_INIT:
+                //
+                // Initialization is complete. FWICT, this should not get here.
+                //
+                break;
+            case PJ_ICE_STRANS_OP_NEGOTIATION:
+                //
+                // Negotiation is complete.
+                //
+            {
+                boost::shared_lock<boost::shared_mutex> lock(mLock);
+                TransportMap::iterator i = mTransportMap.find(transport);
+                if (i == mTransportMap.end())
+                {
+                    //
+                    // XXX This is a "possibly" an exceptional condition. We'll skip the assert/thing for now, but this
+                    // should really log or something.
+                    //
+                }
+                i->second->onComplete(operation, status);
+            }
+                break;
+            case PJ_ICE_STRANS_OP_KEEP_ALIVE:
+                //
+                // Keep alive has successfully completed. FWICT this should not get here.
+                // 
+                break;
+            default:
+        };
+    }
+
+private:
+
+    static TransportMap mTransportMap;
+    static boost::shared_mutex mLock;
+};
+
+//
+// Static member initializations.
+//
+IceCallbackAdapter::TransportMap IceCallbackAdapter::mTransportMap;
+boost::shared_mutex IceCallbackAdapter::mLock;
+
+}
+using namespace ICEMediaSession;
+
+RTPSessionImpl::RTPSessionImpl(const FormatSeq& formats, const PjLibEnvironmentPtr& pjLib,
+        const ReplicatorPtr& replicaService, const StateReplicatorPrx& replicator) :
+    mFormats(formats),
+    mPjLib(pjLib),
+    mReplicaControl(replicaService),
+    mReplicator(replicator),
+    mBasePort(0)
+{
+}
+
+void RTPSessionImpl::initialize(const Ice::PropertiesPtr& properties)
+{
+#if 0
+    //
+    // XXX binding local ports with an ICE transport?
+    //
+    const int minPort = properties->getPropertyAsIntWithDefault("AsteriskSCF.Media.Transport.ICETransport.MinPort",
+            DefaultRTPPortMinimum);
+    const int maxPort = properties->getPropertyAsIntWithDefault("AsteriskSCF.Media.Transport.ICETransport.MaxPort",
+            DefaultRTPPortMaximum);
+    
+    for (int candidatePort = minPort; port < maxPort; candidatePort +=2)
+    {
+        
+    }
+#endif
+    pjmedia_ice_create(mPjLib->getMediaEndpoint(), "ASCF_ICE_MEDIA", 10, 0, &ICECallbackAdapter::onIceComplete,
+            &mTransport);
+}
+
+RTPSessionPrx RTPICESession::create(const Ice::ObjectAdapterPtr& adapter, const Ice::Identity& id,
+        const FormatSeq& formats, pj_pool_factory* factory, const ReplicatPtr& replicaService,
+        const AsteriskSCF::SmartProxy::SmartProxy<RtpStateReplicatorPrx>& stateReplicator)
+{
+    RTPSessionImplPtr servant(new RTPSessionImpl(formats, new PjLibEnvironment(factory), replicaService,
+                    stateReplicator));
+    assert(adapter);
+    servant->initialize(adapter->getCommunicator()->getProperties());
+    return RTPSessionPrx::uncheckedCast(adapter->add(servant, id));
+}
diff --git a/src/RTPICESession.h b/src/RTPICESession.h
new file mode 100644
index 0000000..a886a0c
--- /dev/null
+++ b/src/RTPICESession.h
@@ -0,0 +1,17 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
diff --git a/src/ServiceConfig.h b/src/ServiceConfig.h
new file mode 100644
index 0000000..ff1cf59
--- /dev/null
+++ b/src/ServiceConfig.h
@@ -0,0 +1,35 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+namespace AsteriskSCF
+{
+namespace PJMediaRTP
+{
+
+/**
+ * Default value for where we should start allocating RTP and RTCP ports from.
+ */
+const int DefaultRTPPortMinimum =  10000;
+
+/**
+ * Default value for where we should stop allocating RTP and RTCP ports.
+ */
+const int DefaultRTPPortMaximum = 20000;
+
+}; /* End of namespace PJMediaRTP */
+}; /* End of namespace AsteriskSCF */

commit ddc3a6e767485cd4b5a3ca15ad0f3613826e3bc7
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Apr 19 13:21:42 2011 -0230

    Changes in progress

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1f2b232..cf9d79d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -20,6 +20,8 @@ asterisk_scf_component_add_file(media_rtp_pjmedia RTPSink.cpp)
 asterisk_scf_component_add_file(media_rtp_pjmedia RTPSession.h)
 asterisk_scf_component_add_file(media_rtp_pjmedia RTPSource.h)
 asterisk_scf_component_add_file(media_rtp_pjmedia RTPSink.h)
+asterisk_scf_component_add_file(media_rtp_pjmedia RTPICESession.cpp)
+asterisk_scf_component_add_file(media_rtp_pjmedia RTPICESession.h)
 asterisk_scf_component_add_file(media_rtp_pjmedia RtpStateReplicatorListener.cpp)
 asterisk_scf_component_add_file(media_rtp_pjmedia RtpStateReplicator.h)
 asterisk_scf_component_add_slice(media_rtp_pjmedia ../local-slice/RtpStateReplicationIf.ice)
diff --git a/src/MediaRTPpjmedia.cpp b/src/MediaRTPpjmedia.cpp
index 3c1343e..247a5af 100644
--- a/src/MediaRTPpjmedia.cpp
+++ b/src/MediaRTPpjmedia.cpp
@@ -14,11 +14,11 @@
  * at the top of the source tree.
  */
 
+#include <pjlib.h>
 #include <Ice/Ice.h>
 #include <IceBox/IceBox.h>
 #include <IceUtil/UUID.h>
 
-#include <pjlib.h>
 #include <pjmedia.h>
 
 #include <boost/shared_ptr.hpp>
@@ -335,7 +335,7 @@ RTPMediaServiceImpl::RTPMediaServiceImpl(const Ice::ObjectAdapterPtr& adapter, c
     pj_caching_pool_init(&mCachingPool, &pj_pool_factory_default_policy, 0);
 
     /* Initialize the memory pool that pjmedia will draw from. */
-    mMemoryPool = pj_pool_create(&mCachingPool.factory, "media_rtp_pjmedia", 1000, 1000, NULL);
+    mMemoryPool = pj_pool_create(&mCachingPool.factory, "media_rtp_pjmedia", 1024, 1024, 0);
 }
 
 /**
diff --git a/src/RTPSession.cpp b/src/RTPSession.cpp
index 5911676..b9e6eea 100644
--- a/src/RTPSession.cpp
+++ b/src/RTPSession.cpp
@@ -14,10 +14,10 @@
  * at the top of the source tree.
  */
 
+#include <pjlib.h>
 #include <Ice/Ice.h>
 #include <IceUtil/UUID.h>
 
-#include <pjlib.h>
 #include <pjmedia.h>
 
 #include <AsteriskSCF/Media/MediaIf.h>
@@ -31,6 +31,7 @@
 #include "RTPSession.h"
 #include "RTPSource.h"
 #include "RTPSink.h"
+#include "ServiceConfig.h"
 
 using namespace std;
 using namespace AsteriskSCF::Core::Discovery::V1;
@@ -41,16 +42,6 @@ using namespace AsteriskSCF::System::V1;
 using namespace AsteriskSCF::SmartProxy;
 
 /**
- * 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
@@ -130,6 +121,12 @@ public:
     AsteriskSCF::SmartProxy::SmartProxy<RtpStateReplicatorPrx> mStateReplicator;
 };
 
+
+//
+// TODO: Construction of an object should not add/remove elements to an object adapter IF the lifecycle
+// of the objects (actual and logical) depend on the successful construction of the object being created
+//
+
 /**
  * Constructor for the RTPSessionImpl class (used by Ice).
  */
@@ -155,7 +152,11 @@ RTPSessionImpl::RTPSessionImpl(const Ice::ObjectAdapterPtr& adapter, const Forma
     }
 
     /* 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)
+
+    //
+    // The candidate ports increment by two to allow "room" for both a control and a data port.
+    //
+    for (int port = DefaultRTPPortMinimum; port < DefaultRTPPortMaximum; port += 2)
     {
         if ((status = pjmedia_transport_udp_create2(mImpl->mEndpoint, "RTP", NULL, port, 0, &mImpl->mTransport)) ==
                 PJ_SUCCESS)
diff --git a/src/RTPSink.cpp b/src/RTPSink.cpp
index fb612cb..7e8fe7e 100644
--- a/src/RTPSink.cpp
+++ b/src/RTPSink.cpp
@@ -14,10 +14,10 @@
  * at the top of the source tree.
  */
 
+#include <pjlib.h>
 #include <Ice/Ice.h>
 #include <IceUtil/UUID.h>
 
-#include <pjlib.h>
 #include <pjmedia.h>
 
 #include <AsteriskSCF/Media/MediaIf.h>
diff --git a/src/RtpStateReplicatorApp.cpp b/src/RtpStateReplicatorApp.cpp
index 78e8ae1..5c4476e 100644
--- a/src/RtpStateReplicatorApp.cpp
+++ b/src/RtpStateReplicatorApp.cpp
@@ -14,13 +14,13 @@
  * at the top of the source tree.
  */
 
+#include <pjlib.h>
+
 #include <Ice/Ice.h>
 #include <IceUtil/UUID.h>
 #include <IceStorm/IceStorm.h>
 #include <IceBox/IceBox.h>
 
-#include <pjlib.h>
-
 #include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.h>
 #include <AsteriskSCF/System/Component/ComponentServiceIf.h>
 #include <AsteriskSCF/Logger/IceLogger.h>
diff --git a/src/RtpStateReplicatorListener.cpp b/src/RtpStateReplicatorListener.cpp
index a42c7b5..0aa87a5 100644
--- a/src/RtpStateReplicatorListener.cpp
+++ b/src/RtpStateReplicatorListener.cpp
@@ -13,13 +13,12 @@
  * the GNU General Public License Version 2. See the LICENSE.txt file
  * at the top of the source tree.
  */
-
+#include <pjlib.h>
 #include <IceUtil/UUID.h>
 
 #include <boost/thread.hpp>
 #include <boost/shared_ptr.hpp>
 
-#include <pjlib.h>
 #include <pjmedia.h>
 
 #include <AsteriskSCF/System/Component/ReplicaIf.h>

commit fb3751f703ad0d1fb4b3ba17d0f3db484fdeca53
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Apr 1 13:16:55 2011 -0230

    Capture changes in progress

diff --git a/src/RTPSession.cpp b/src/RTPSession.cpp
index 2ab6074..5911676 100644
--- a/src/RTPSession.cpp
+++ b/src/RTPSession.cpp
@@ -23,6 +23,7 @@
 #include <AsteriskSCF/Media/MediaIf.h>
 #include <AsteriskSCF/Media/RTP/MediaRTPIf.h>
 #include <AsteriskSCF/System/Component/ReplicaIf.h>
+#include <AsteriskSCF/System/ExceptionsIf.h>
 #include <AsteriskSCF/SmartProxy.h>
 
 #include "RtpStateReplicationIf.h"
@@ -36,6 +37,7 @@ using namespace AsteriskSCF::Core::Discovery::V1;
 using namespace AsteriskSCF::Media::V1;
 using namespace AsteriskSCF::Media::RTP::V1;
 using namespace AsteriskSCF::System::Component::V1;
+using namespace AsteriskSCF::System::V1;
 using namespace AsteriskSCF::SmartProxy;
 
 /**
@@ -137,6 +139,10 @@ RTPSessionImpl::RTPSessionImpl(const Ice::ObjectAdapterPtr& adapter, const Forma
     mImpl(new RTPSessionImplPriv(adapter, formats, replicaService, stateReplicator))
 {
     /* Add ourselves to the ICE ASM so we can be used. */
+
+    //
+    // XXX: It's sketchy to add a servant to an object adapter in it's constructor.
+    //
     mImpl->mProxy = RTPSessionPrx::uncheckedCast(adapter->addWithUUID(this));
 
     /* Create an endpoint in pjmedia for our media. */
@@ -145,6 +151,7 @@ RTPSessionImpl::RTPSessionImpl(const Ice::ObjectAdapterPtr& adapter, const Forma
     if (status != PJ_SUCCESS)
     {
         /* TODO: This is bad... we can't go on! */
+        throw InternalInitializationException("Unable to created PJMEDIA endpoint!");
     }
 
     /* Now create some transport we can use to actually send or receive the media. */

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


-- 
asterisk-scf/integration/media_rtp_pjmedia.git



More information about the asterisk-scf-commits mailing list