[asterisk-scf-commits] asterisk-scf/integration/bridging.git branch "mediamixer" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Wed Aug 31 16:21:35 CDT 2011


branch "mediamixer" has been updated
       via  c503f171554fa572219ebdcecba7729a963b8128 (commit)
      from  e5cae4226e48ac5ba477e598292e0c185e3188bf (commit)

Summary of changes:
 src/MediaMixer.cpp   |  138 +++++++++++++++++++++++++++++++++++++++++++++-----
 src/MediaSplicer.cpp |    9 ++--
 2 files changed, 130 insertions(+), 17 deletions(-)


- Log -----------------------------------------------------------------
commit c503f171554fa572219ebdcecba7729a963b8128
Author: Joshua Colp <jcolp at digium.com>
Date:   Wed Aug 31 18:26:09 2011 -0300

    Put in a slew of fixes which gets things to the point where a mixer is setup and frames go to it as expected. Hangup is not currently functional though, it seems.

diff --git a/src/MediaMixer.cpp b/src/MediaMixer.cpp
index 594d95d..f0f703d 100755
--- a/src/MediaMixer.cpp
+++ b/src/MediaMixer.cpp
@@ -145,6 +145,8 @@ public:
     {
         boost::unique_lock<boost::shared_mutex> lock(mLock);
 
+	std::cout << "Frame goes in" << std::endl;
+
         mFrames.insert(mFrames.begin(), frames.begin(), frames.end());
     }
     
@@ -186,10 +188,9 @@ public:
     {
         boost::unique_lock<boost::shared_mutex> lock(mLock);
 
-        mProvidedFrame = mFrames.back();
-
-        if (mProvidedFrame)
+        if (!mFrames.empty())
         {
+            mProvidedFrame = mFrames.back();
             mFrames.pop_back();
         }
 
@@ -225,6 +226,14 @@ public:
         return mProxy;
     }
 
+    /**
+     * Internal function which returns the local source.
+     */
+    MediaMixerSourcePtr getLocalSource()
+    {
+        return mLocalSource;
+    }
+
 private:
     /**
      * Lock which protects this sink.
@@ -268,10 +277,36 @@ private:
     FramePtr mProvidedFrame;
 };
 
+/**
+ * Simple callback object used when writing to sinks.
+ */
+class WriteCallback : public IceUtil::Shared
+{
+public:
+    void writtenCB()
+    {
+    }
+
+    void failureCB(const Ice::Exception&)
+    {
+    }
+};
+
+/**
+ * Smart pointer for the above WriteCallback class.
+ */
+typedef IceUtil::Handle<WriteCallback> WriteCallbackPtr;
+
 class MediaMixerI
 {
 public:
-    MediaMixerI(const Ice::ObjectAdapterPtr& adapter) : mAdapter(adapter), mTimer(new IceUtil::Timer()) { }
+    MediaMixerI(const Ice::ObjectAdapterPtr& adapter) : mAdapter(adapter), mTimer(new IceUtil::Timer()),
+                                                        mCallback(new WriteCallback()) { }
+
+    /**
+     * Lock which protects the mixer.
+     */
+    boost::shared_mutex mLock;
 
     /**
      * Object adapter that sinks/sources are on.
@@ -292,6 +327,11 @@ public:
      * Timer thread used to mix the media.
      */
     IceUtil::TimerPtr mTimer;
+
+    /**
+     * Callback object for when writing to sinks.
+     */
+    WriteCallbackPtr mCallback;
 };
 
 MediaMixer::MediaMixer(const Ice::ObjectAdapterPtr& adapter) : mImpl(new MediaMixerI(adapter))
@@ -302,44 +342,116 @@ MediaMixer::MediaMixer(const Ice::ObjectAdapterPtr& adapter) : mImpl(new MediaMi
 void MediaMixer::createMixing(const Ice::Identity& sinkId, AsteriskSCF::Media::V1::StreamSinkPrx& mixerSink,
                               const Ice::Identity& sourceId, AsteriskSCF::Media::V1::StreamSourcePrx& mixerSource)
 {
+    boost::unique_lock<boost::shared_mutex> lock(mImpl->mLock);
+
     // The source is where mixed audio will originate from, within this implementation it essentially acts
     // as a store of sinks we need to write to for this source
-    MediaMixerSourcePtr source = new MediaMixerSource(this);
-    mImpl->mSources.push_back(source);
     Ice::Identity id = sourceId;
     id.name += ".mixer";
-    mixerSource = StreamSourcePrx::uncheckedCast(mImpl->mAdapter->add(source, id));
-    source->setProxy(mixerSource);
+    MediaMixerSourcePtr source;
+    if (mImpl->mAdapter->find(id))
+    {
+        mixerSource = StreamSourcePrx::uncheckedCast(mImpl->mAdapter->createProxy(id));
+    }
+    else
+    {
+        source = new MediaMixerSource(this);
+        mImpl->mSources.push_back(source);
+        mixerSource = StreamSourcePrx::uncheckedCast(mImpl->mAdapter->add(source, id));
+        source->setProxy(mixerSource);
+    }
 
     // The sink is where the source will send audio to to be mixed into the bridge, the reason the local source
     // is associated is because we need to know what media to remove from the mixed frame when writing out
-    MediaMixerSinkPtr sink = new MediaMixerSink(this, source);
-    mImpl->mSinks.push_back(sink);
     id = sinkId;
     id.name += ".mixer";
-    mixerSink = StreamSinkPrx::uncheckedCast(mImpl->mAdapter->add(sink, id));
-    sink->setProxy(mixerSink);
+    if (mImpl->mAdapter->find(id))
+    {
+        mixerSink = StreamSinkPrx::uncheckedCast(mImpl->mAdapter->createProxy(id));
+    }
+    else
+    {
+        MediaMixerSinkPtr sink = new MediaMixerSink(this, source);
+        mImpl->mSinks.push_back(sink);
+        mixerSink = StreamSinkPrx::uncheckedCast(mImpl->mAdapter->add(sink, id));
+        sink->setProxy(mixerSink);
+    }
 }
 
 void MediaMixer::runTimerTask()
 {
-    // MIXING CODE GOES HERE
+    std::vector<MediaMixerSinkPtr> sinks;
+
+    {
+        boost::shared_lock<boost::shared_mutex> lock(mImpl->mLock);
+        sinks = mImpl->mSinks;
+    }
+
+    FramePtr frame = new Frame();
+
+    for (std::vector<MediaMixerSinkPtr>::const_iterator sink = sinks.begin();
+         sink != sinks.end();
+         ++sink)
+    {
+        FramePtr sinkFrame = (*sink)->getFrame();
+
+        // If no frame exists for us to mix in skip doing so
+        if (!sinkFrame)
+        {
+            continue;
+        }
+    }
+
+    for (std::vector<MediaMixerSinkPtr>::const_iterator sink = sinks.begin();
+         sink != sinks.end();
+         ++sink)
+    {
+        FramePtr sinkFrame = (*sink)->popFrame();
+	FramePtr theirFrame(frame);
+
+        if (sinkFrame)
+        {
+            // If a frame was mixed in mix it out so we don't send their own audio to them
+	    theirFrame = FramePtr::dynamicCast(frame->ice_clone());
+        }
+
+        // Send this frame to all the sinks we should
+        StreamSinkSeq sourceSinks = (*sink)->getLocalSource()->getSinks(Ice::Current());
+
+	FrameSeq frames;
+	frames.push_back(theirFrame);
+
+        for (StreamSinkSeq::const_iterator sourceSink = sourceSinks.begin();
+             sourceSink != sourceSinks.end();
+             ++sourceSink)
+        {
+            (*sourceSink)->begin_write(frames, newCallback_StreamSink_write(mImpl->mCallback,
+                                                                            &WriteCallback::writtenCB,
+                                                                            &WriteCallback::failureCB));
+        }
+    }
 }
 
 void MediaMixer::removeSource(const MediaMixerSourcePtr& source, const StreamSourcePrx& proxy)
 {
+    boost::unique_lock<boost::shared_mutex> lock(mImpl->mLock);
+
     mImpl->mSources.erase(std::remove(mImpl->mSources.begin(), mImpl->mSources.end(), source), mImpl->mSources.end());
     mImpl->mAdapter->remove(proxy->ice_getIdentity());
 }
 
 void MediaMixer::removeSink(const MediaMixerSinkPtr& sink, const StreamSinkPrx& proxy)
 {
+    boost::unique_lock<boost::shared_mutex> lock(mImpl->mLock);
+
     mImpl->mSinks.erase(std::remove(mImpl->mSinks.begin(), mImpl->mSinks.end(), sink), mImpl->mSinks.end());
     mImpl->mAdapter->remove(proxy->ice_getIdentity());
 }
 
 void MediaMixer::stop()
 {
+    boost::unique_lock<boost::shared_mutex> lock(mImpl->mLock);
+
     mImpl->mTimer->destroy();
 
     for (std::vector<MediaMixerSinkPtr>::const_iterator sink = mImpl->mSinks.begin();
diff --git a/src/MediaSplicer.cpp b/src/MediaSplicer.cpp
index 6b2ccab..42b19df 100755
--- a/src/MediaSplicer.cpp
+++ b/src/MediaSplicer.cpp
@@ -398,7 +398,7 @@ public:
         mBridgeId(bridgeId),
         mReplicator(replicator),
         mLogger(logger),
-        mMixer(false),
+        mMixer(true),
 	mAdapter(adapter)
     {
     }
@@ -508,7 +508,7 @@ public:
         }
 
         MediaMixerPtr mixer;
-        while ((mixer = mMediaMixers.back()))
+        while (!mMediaMixers.empty())
         {
             mixer->stop();
             mMediaMixers.pop_back();
@@ -555,10 +555,10 @@ public:
                 continue;
             }
 
-	    MediaMixerPtr mixer = mixers.back();
+	    MediaMixerPtr mixer;
 
 	    // How do we determine what the 'right' mixer is to use?
-	    if (mixer == 0)
+            if (mixers.empty())
 	    {
 		mLogger(Debug) << FUNLOG << ": creating media mixer.";
 		mixer = new MediaMixer(mAdapter);
@@ -567,6 +567,7 @@ public:
 	    else
 	    {
 		mLogger(Debug) << FUNLOG << ": using found media mixer.";
+		mixer = mixers.back();
 		mixers.pop_back();
 	    }
 

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


-- 
asterisk-scf/integration/bridging.git



More information about the asterisk-scf-commits mailing list