[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
Thu Oct 6 14:42:20 CDT 2011


branch "mediamixer" has been updated
       via  eea7583e664c35e6d36e8594e8825790d9880261 (commit)
      from  2f1624d27cf6613124b67af667ce0165c9283331 (commit)

Summary of changes:
 src/MediaMixer.cpp   |   52 ++++++++++++++++++++++++++++++++-------------
 src/MediaMixer.h     |    2 +-
 src/MediaSplicer.cpp |   57 ++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 80 insertions(+), 31 deletions(-)


- Log -----------------------------------------------------------------
commit eea7583e664c35e6d36e8594e8825790d9880261
Author: Joshua Colp <jcolp at digium.com>
Date:   Thu Oct 6 16:42:39 2011 -0300

    Make the mixer code format aware and get it properly mixing. Next up is fine tuning timing.

diff --git a/src/MediaMixer.cpp b/src/MediaMixer.cpp
index 7c92704..e33c2df 100755
--- a/src/MediaMixer.cpp
+++ b/src/MediaMixer.cpp
@@ -14,12 +14,16 @@
  * at the top of the source tree.
  */
 #include "MediaMixer.h"
+
+#include <AsteriskSCF/Media/Formats/AudioFormats.h>
+
 #include <Ice/Ice.h>
 #include <IceUtil/Shared.h>
 #include <IceUtil/Handle.h>
 
 using namespace AsteriskSCF::System::Logging;
 using namespace AsteriskSCF::Media::V1;
+using namespace AsteriskSCF::Media::Formats::Audio::V1;
 using namespace std;
 
 namespace AsteriskSCF
@@ -298,8 +302,9 @@ typedef IceUtil::Handle<WriteCallback> WriteCallbackPtr;
 class MediaMixerI
 {
 public:
-    MediaMixerI(const Ice::ObjectAdapterPtr& adapter) : mAdapter(adapter), mTimer(new IceUtil::Timer()),
-                                                        mCallback(new WriteCallback()) { }
+    MediaMixerI(const Ice::ObjectAdapterPtr& adapter, const FormatPtr& format) : mAdapter(adapter), mFormat(format),
+										 mTimer(new IceUtil::Timer()),
+										 mCallback(new WriteCallback()) { }
 
     /**
      * Lock which protects the mixer.
@@ -312,6 +317,11 @@ public:
     Ice::ObjectAdapterPtr mAdapter;
 
     /**
+     * Format for produced frames.
+     */
+    FormatPtr mFormat;
+
+    /**
      * Vector of sinks for media.
      */
     std::vector<MediaMixerSinkPtr> mSinks;
@@ -374,7 +384,7 @@ static short saturatedSignedLinearSubtract(short input, short value)
     }
 }
 
-MediaMixer::MediaMixer(const Ice::ObjectAdapterPtr& adapter) : mImpl(new MediaMixerI(adapter))
+MediaMixer::MediaMixer(const Ice::ObjectAdapterPtr& adapter, const FormatPtr& format) : mImpl(new MediaMixerI(adapter, format))
 {
     mImpl->mTimer->scheduleRepeated(this, IceUtil::Time::milliSeconds(MIXING_INTERVAL));
 }
@@ -428,8 +438,9 @@ void MediaMixer::runTimerTask()
     }
 
     FramePtr frame = new Frame();
+    frame->mediaFormat = mImpl->mFormat;
 
-    ByteSeqPayloadPtr mixedPayload = new ByteSeqPayload();
+    ShortSeqPayloadPtr mixedPayload = new ShortSeqPayload();
     frame->payload = mixedPayload;
 
     for (std::vector<MediaMixerSinkPtr>::const_iterator sink = sinks.begin();
@@ -444,17 +455,26 @@ void MediaMixer::runTimerTask()
             continue;
         }
 
-        ByteSeqPayloadPtr payload = ByteSeqPayloadPtr::dynamicCast(sinkFrame->payload);
+        ShortSeqPayloadPtr payload = ShortSeqPayloadPtr::dynamicCast(sinkFrame->payload);
 
-        // We only currently support byte sequence payloads
+        // We only currently support short sequence payloads
         if (!payload)
         {
-            continue;
-        }
+            continue; 
+       }
 
-        std::transform(mixedPayload->payload.begin(), mixedPayload->payload.end(),
-                       payload->payload.begin(), payload->payload.end(),
-                       saturatedSignedLinearAdd);
+        // If no audio exists within the mixedPayload yet just copy this frame in, otherwise mix it in
+        if (!mixedPayload->payload.size())
+        {
+            mixedPayload->payload.resize(payload->payload.size());
+            std::copy(payload->payload.begin(), payload->payload.end(), mixedPayload->payload.begin());
+        }
+        else
+        {
+            std::transform(mixedPayload->payload.begin(), mixedPayload->payload.end(),
+                           payload->payload.begin(), mixedPayload->payload.begin(),
+                           saturatedSignedLinearAdd);
+        }
     }
 
     for (std::vector<MediaMixerSinkPtr>::const_iterator sink = sinks.begin();
@@ -466,15 +486,17 @@ void MediaMixer::runTimerTask()
 
         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());
 
-            ByteSeqPayloadPtr sinkPayload = ByteSeqPayloadPtr::dynamicCast(sinkFrame->payload);
-            ByteSeqPayloadPtr payload = ByteSeqPayloadPtr::dynamicCast(theirFrame->payload);
+            ShortSeqPayloadPtr sinkPayload = ShortSeqPayloadPtr::dynamicCast(sinkFrame->payload);
 
+            ShortSeqPayloadPtr payload = new ShortSeqPayload();
+            payload->payload.resize(mixedPayload->payload.size());
+            std::copy(mixedPayload->payload.begin(), mixedPayload->payload.end(), payload->payload.begin());
             std::transform(payload->payload.begin(), payload->payload.end(),
-                           sinkPayload->payload.begin(), sinkPayload->payload.end(),
+                           sinkPayload->payload.begin(), payload->payload.begin(),
                            saturatedSignedLinearSubtract);
+            theirFrame->payload = payload;
         }
 
         // Send this frame to all the sinks we should
diff --git a/src/MediaMixer.h b/src/MediaMixer.h
index 5475755..d167e25 100644
--- a/src/MediaMixer.h
+++ b/src/MediaMixer.h
@@ -49,7 +49,7 @@ class MediaMixerI;
 class MediaMixer : public IceUtil::TimerTask
 {
 public:
-    MediaMixer(const Ice::ObjectAdapterPtr&);
+    MediaMixer(const Ice::ObjectAdapterPtr&, const AsteriskSCF::Media::V1::FormatPtr&);
 
     void createMixing(const Ice::Identity&, AsteriskSCF::Media::V1::StreamSinkPrx&,
                       const Ice::Identity&, AsteriskSCF::Media::V1::StreamSourcePrx&);
diff --git a/src/MediaSplicer.cpp b/src/MediaSplicer.cpp
index d9a7cef..f6a3072 100755
--- a/src/MediaSplicer.cpp
+++ b/src/MediaSplicer.cpp
@@ -15,6 +15,7 @@
  */
 #include "MediaSplicer.h"
 #include "MediaMixer.h"
+#include <AsteriskSCF/Media/Formats/AudioFormats.h>
 #include <IceUtil/Shared.h>
 #include <IceUtil/Handle.h>
 #include "BridgeServiceConfig.h"
@@ -38,6 +39,7 @@
 //
 using namespace AsteriskSCF::System::Logging;
 using namespace AsteriskSCF::Media::V1;
+using namespace AsteriskSCF::Media::Formats::Audio::V1;
 using namespace AsteriskSCF::Replication::BridgeService::V1;
 using namespace std;
 
@@ -507,14 +509,15 @@ public:
             return;
         }
 
-        MediaMixerPtr mixer;
-        while (!mMediaMixers.empty())
+        for (MediaMixers::const_iterator mixer = mMediaMixers.begin();
+             mixer != mMediaMixers.end();
+             ++mixer)
         {
-            mixer = mMediaMixers.back();
-            mixer->stop();
-            mMediaMixers.pop_back();
+            mixer->second->stop();
         }
 
+        mMediaMixers.clear();
+
         mMixer = false;
     }
 
@@ -557,19 +560,43 @@ public:
             }
 
 	    MediaMixerPtr mixer;
+            bool disallowed = false;
 
-	    // How do we determine what the 'right' mixer is to use?
-            if (mixers.empty())
-	    {
-		mLogger(Debug) << FUNLOG << ": creating media mixer.";
-		mixer = new MediaMixer(mAdapter);
-		mMediaMixers.push_back(mixer);
+            // Only allow signed linear formats to create or find a mixer
+            for (FormatSeq::const_iterator format = stream->second->formats.begin();
+                 format != stream->second->formats.end();
+                 ++format)
+            {
+                SignedLinearPtr slin = SignedLinearPtr::dynamicCast((*format));
+
+                if (!slin)
+                {
+                    disallowed = true;
+                    break;
+                }
+            }
+
+            // If the stream contains an unsupported format do not go further, do not pass go
+            if (disallowed == true)
+            {
+                continue;
+            }
+
+            // Look for a mixer based on the format on this stream
+            std::string format = stream->second->formats.front()->name;
+            MediaMixers::const_iterator existingMixer = mixers.find(format);
+
+            if (existingMixer == mixers.end())
+            {
+                mLogger(Debug) << FUNLOG << ": creating media mixer for format " << format;
+                mixer = new MediaMixer(mAdapter, stream->second->formats.front());
+                mMediaMixers.insert(make_pair(format, mixer));
 	    }
 	    else
 	    {
-		mLogger(Debug) << FUNLOG << ": using found media mixer.";
-		mixer = mixers.back();
-		mixers.pop_back();
+		mLogger(Debug) << FUNLOG << ": using found media mixer for format " << format;
+		mixer = existingMixer->second;
+                mixers.erase(format);
 	    }
 
             StreamSinkSeq sinks = stream->second->sinks;
@@ -693,7 +720,7 @@ private:
 
     MediaConnectors mConnectors;
 
-    typedef vector<MediaMixerPtr> MediaMixers;
+    typedef std::map<std::string, MediaMixerPtr> MediaMixers;
 
     MediaMixers mMediaMixers;
 

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


-- 
asterisk-scf/integration/bridging.git



More information about the asterisk-scf-commits mailing list