[asterisk-scf-commits] asterisk-scf/integration/media_operations_core.git branch "g722" created.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Wed Aug 31 19:57:52 CDT 2011


branch "g722" has been created
        at  6a39d3d26db6669fee7ea19d9aa9dbc9310923fb (commit)

- Log -----------------------------------------------------------------
commit 6a39d3d26db6669fee7ea19d9aa9dbc9310923fb
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Aug 31 19:59:08 2011 -0500

    Add G.722 tests. They pass.

diff --git a/src/g722.cpp b/src/g722.cpp
index 7d60640..112bbec 100644
--- a/src/g722.cpp
+++ b/src/g722.cpp
@@ -76,7 +76,7 @@ private:
                 outsamples = g722_decode(&mDecodeToSlin8, outbuffer16, &inPayload->payload.front(), inFormat->frameSize);
             }
 
-            ShortSeqPayloadPtr outPayload(new ShortSeqPayload(Ice::ShortSeq(outsamples)));
+            ShortSeqPayloadPtr outPayload(new ShortSeqPayload(Ice::ShortSeq(outbuffer16, outbuffer16 + outsamples)));
             outFormat->frameSize = outsamples;
             return new Frame(outFormat, outPayload);
         }
@@ -105,7 +105,7 @@ private:
                 outlen = g722_encode(&mEncodeFromSlin8, outbuffer8, &inPayload->payload.front(), inFormat->frameSize);
             }
 
-            ByteSeqPayloadPtr outPayload(new ByteSeqPayload(Ice::ByteSeq(outlen)));
+            ByteSeqPayloadPtr outPayload(new ByteSeqPayload(Ice::ByteSeq(outbuffer8, outbuffer8 + outlen)));
             outFormat->frameSize = outlen;
             return new Frame(outFormat, outPayload);
         }
diff --git a/test/TestMediaOperations.cpp b/test/TestMediaOperations.cpp
index 2df6731..f4bec35 100644
--- a/test/TestMediaOperations.cpp
+++ b/test/TestMediaOperations.cpp
@@ -60,6 +60,8 @@ public:
 
     AudioFormatPtr slin16;
 
+    AudioFormatPtr g722;
+
     TestStreamSinkPtr ulawSink;
 
     StreamSinkPrx ulawSinkProxy;
@@ -78,6 +80,10 @@ public:
 
     TestStreamSourcePtr alawSource;
 
+    TestStreamSinkPtr g722Sink;
+
+    StreamSinkPrx g722SinkProxy;
+
     StreamSourcePrx alawSourceProxy;
 
     TestStreamSourcePtr ulawSource;
@@ -92,6 +98,10 @@ public:
 
     StreamSourcePrx slin16SourceProxy;
 
+    TestStreamSourcePtr g722Source;
+
+    StreamSourcePrx g722SourceProxy;
+
     FramePtr sampleAlawFrame;
 
     size_t sampleAlawFrameSize;
@@ -107,6 +117,10 @@ public:
     FramePtr sampleSlin16Frame;
 
     size_t sampleSlin16FrameSize;
+
+    FramePtr sampleG722Frame;
+
+    size_t sampleG722FrameSize;
 };
 
 static SharedTestData Testbed;
@@ -170,6 +184,30 @@ static uint16_t sampleSlin16[] = {
     0x90c0, 0xc3c6, 0xc9cc, 0xcfd2,
 };
 
+//Copied from Asterisk's ex_g722.h file
+static uint8_t sampleG722[] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
 /**
  * Wrapper class around pj_thread_desc.
  * (copied from PJSipManager.h in the sip repo)
@@ -274,6 +312,9 @@ struct GlobalIceFixture
             Testbed.slin16->name = SignedLinear16Name;
             Testbed.slin16->sampleRate = 16000;
 
+            Testbed.g722 = new G722();
+            Testbed.g722->name = G722Name;
+
             Testbed.sampleAlawFrame = new Frame(Testbed.alaw, new ByteSeqPayload(Ice::ByteSeq(sampleAlaw, sampleAlaw + sizeof(sampleAlaw))));
             Testbed.sampleAlawFrameSize = sizeof(sampleAlaw);
 
@@ -287,6 +328,9 @@ struct GlobalIceFixture
             ShortSeqPayloadPtr slin16Payload(new ShortSeqPayload(Ice::ShortSeq(sampleSlin16, sampleSlin16 + (sizeof(sampleSlin16) / 2))));
             Testbed.sampleSlin16Frame = new Frame(Testbed.slin16, slin16Payload);
             Testbed.sampleSlin16FrameSize = slin16Payload->payload.size();
+
+            Testbed.sampleG722Frame = new Frame(Testbed.g722, new ByteSeqPayload(Ice::ByteSeq(sampleG722, sampleG722 + sizeof(sampleG722))));
+            Testbed.sampleG722FrameSize = sizeof(sampleG722);
         }
         catch (const Ice::Exception& ex)
         {
@@ -344,6 +388,12 @@ public:
 
         Testbed.slin16Sink = new TestStreamSink(Testbed.slin16);
         Testbed.slin16SinkProxy = StreamSinkPrx::uncheckedCast(Testbed.adapter->addWithUUID(Testbed.slin16Sink));
+
+        Testbed.g722Source = new TestStreamSource(Testbed.g722);
+        Testbed.g722SourceProxy = StreamSourcePrx::uncheckedCast(Testbed.adapter->addWithUUID(Testbed.g722Source));
+
+        Testbed.g722Sink = new TestStreamSink(Testbed.g722);
+        Testbed.g722SinkProxy = StreamSinkPrx::uncheckedCast(Testbed.adapter->addWithUUID(Testbed.g722Sink));
     }
     ~PerTestFixture()
     {
@@ -354,6 +404,12 @@ public:
         Testbed.adapter->remove(Testbed.alawSinkProxy->ice_getIdentity());
         Testbed.adapter->remove(Testbed.ulawSourceProxy->ice_getIdentity());
         Testbed.adapter->remove(Testbed.alawSourceProxy->ice_getIdentity());
+        Testbed.adapter->remove(Testbed.slin8SourceProxy->ice_getIdentity());
+        Testbed.adapter->remove(Testbed.slin8SinkProxy->ice_getIdentity());
+        Testbed.adapter->remove(Testbed.slin16SourceProxy->ice_getIdentity());
+        Testbed.adapter->remove(Testbed.slin16SinkProxy->ice_getIdentity());
+        Testbed.adapter->remove(Testbed.g722SourceProxy->ice_getIdentity());
+        Testbed.adapter->remove(Testbed.g722SinkProxy->ice_getIdentity());
     }
 };
 
@@ -667,3 +723,240 @@ BOOST_FIXTURE_TEST_CASE(resample16To8, PerTestFixture)
         BOOST_CHECK((int) payload->payload.size() == audio->frameSize);
     }
 }
+
+BOOST_FIXTURE_TEST_CASE(slin8toG722, PerTestFixture)
+{
+    size_t numFramesToTranslate = 10;
+
+    //For this test, we have to base the resultant frame on the size of the input frame.
+
+    Testbed.g722->frameSize = Testbed.sampleG722FrameSize;
+
+    MediaOperationServiceLocatorParamsPtr slinToG722Params = createLocatorParams(Testbed.slin8, Testbed.g722);
+
+    MediaOperationFactoryPrx slinToG722Factory =
+        MediaOperationFactoryPrx::checkedCast(Testbed.locator->locate(slinToG722Params));
+
+    MediaOperationPrx slinToG722Translator =
+        slinToG722Factory->createMediaOperation(Testbed.slin8SourceProxy, Testbed.g722SinkProxy);
+
+    StreamSinkPrx translatorSink = slinToG722Translator->getSink();
+    StreamSourcePrx translatorSource = slinToG722Translator->getSource();
+
+    Testbed.slin8SourceProxy->addSink(translatorSink);
+    Testbed.g722SinkProxy->setSource(translatorSource);
+
+    translatorSource->addSink(Testbed.g722SinkProxy);
+    translatorSink->setSource(Testbed.slin8SourceProxy);
+
+    FrameSeq slin8Frames(numFramesToTranslate, Testbed.sampleSlin8Frame);
+
+    try
+    {
+        Testbed.slin8Source->feedFramesToTranslator(slin8Frames);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        std::stringstream str;
+        str << "Exception caught trying to translate slin8 frames: " << ex.what();
+        BOOST_FAIL(str.str());
+    }
+
+    FrameSeq framesWritten = Testbed.g722Sink->getFrames();
+
+    BOOST_CHECK(framesWritten.size() == numFramesToTranslate);
+
+    for (FrameSeq::iterator iter = framesWritten.begin();
+            iter != framesWritten.end(); ++iter)
+    {
+        BOOST_CHECK(G722Ptr::dynamicCast((*iter)->mediaFormat) != 0);
+
+        ByteSeqPayloadPtr payload = ByteSeqPayloadPtr::dynamicCast((*iter)->payload);
+
+        BOOST_REQUIRE(payload != 0);
+
+        AudioFormatPtr audio = AudioFormatPtr::dynamicCast((*iter)->mediaFormat);
+
+        BOOST_REQUIRE(audio != 0);
+
+        BOOST_CHECK((int) payload->payload.size() == audio->frameSize);
+    }
+}
+
+BOOST_FIXTURE_TEST_CASE(slin16toG722, PerTestFixture)
+{
+    size_t numFramesToTranslate = 10;
+
+    //For this test, we have to base the resultant frame on the size of the input frame.
+
+    Testbed.g722->frameSize = Testbed.sampleG722FrameSize;
+
+    MediaOperationServiceLocatorParamsPtr slinToG722Params = createLocatorParams(Testbed.slin16, Testbed.g722);
+
+    MediaOperationFactoryPrx slinToG722Factory =
+        MediaOperationFactoryPrx::checkedCast(Testbed.locator->locate(slinToG722Params));
+
+    MediaOperationPrx slinToG722Translator =
+        slinToG722Factory->createMediaOperation(Testbed.slin16SourceProxy, Testbed.g722SinkProxy);
+
+    StreamSinkPrx translatorSink = slinToG722Translator->getSink();
+    StreamSourcePrx translatorSource = slinToG722Translator->getSource();
+
+    Testbed.slin16SourceProxy->addSink(translatorSink);
+    Testbed.g722SinkProxy->setSource(translatorSource);
+
+    translatorSource->addSink(Testbed.g722SinkProxy);
+    translatorSink->setSource(Testbed.slin16SourceProxy);
+
+    FrameSeq slin16Frames(numFramesToTranslate, Testbed.sampleSlin16Frame);
+
+    try
+    {
+        Testbed.slin16Source->feedFramesToTranslator(slin16Frames);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        std::stringstream str;
+        str << "Exception caught trying to translate slin16 frames: " << ex.what();
+        BOOST_FAIL(str.str());
+    }
+
+    FrameSeq framesWritten = Testbed.g722Sink->getFrames();
+
+    BOOST_CHECK(framesWritten.size() == numFramesToTranslate);
+
+    for (FrameSeq::iterator iter = framesWritten.begin();
+            iter != framesWritten.end(); ++iter)
+    {
+        BOOST_CHECK(G722Ptr::dynamicCast((*iter)->mediaFormat) != 0);
+
+        ByteSeqPayloadPtr payload = ByteSeqPayloadPtr::dynamicCast((*iter)->payload);
+
+        BOOST_REQUIRE(payload != 0);
+
+        AudioFormatPtr audio = AudioFormatPtr::dynamicCast((*iter)->mediaFormat);
+
+        BOOST_REQUIRE(audio != 0);
+
+        BOOST_CHECK((int) payload->payload.size() == audio->frameSize);
+    }
+}
+
+BOOST_FIXTURE_TEST_CASE(g722ToSlin8, PerTestFixture)
+{
+    size_t numFramesToTranslate = 10;
+
+    //For this test, we have to base the resultant frame on the size of the input frame.
+
+    Testbed.slin8->frameSize = Testbed.sampleSlin8FrameSize;
+
+    MediaOperationServiceLocatorParamsPtr g722ToSlinParams = createLocatorParams(Testbed.g722, Testbed.slin8);
+
+    MediaOperationFactoryPrx g722ToSlinFactory =
+        MediaOperationFactoryPrx::checkedCast(Testbed.locator->locate(g722ToSlinParams));
+
+    MediaOperationPrx g722ToSlinTranslator =
+        g722ToSlinFactory->createMediaOperation(Testbed.g722SourceProxy, Testbed.slin8SinkProxy);
+
+    StreamSinkPrx translatorSink = g722ToSlinTranslator->getSink();
+    StreamSourcePrx translatorSource = g722ToSlinTranslator->getSource();
+
+    Testbed.g722SourceProxy->addSink(translatorSink);
+    Testbed.slin8SinkProxy->setSource(translatorSource);
+
+    translatorSource->addSink(Testbed.slin8SinkProxy);
+    translatorSink->setSource(Testbed.g722SourceProxy);
+
+    FrameSeq g722Frames(numFramesToTranslate, Testbed.sampleG722Frame);
+
+    try
+    {
+        Testbed.g722Source->feedFramesToTranslator(g722Frames);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        std::stringstream str;
+        str << "Exception caught trying to translate G.722 frames: " << ex.what();
+        BOOST_FAIL(str.str());
+    }
+
+    FrameSeq framesWritten = Testbed.slin8Sink->getFrames();
+
+    BOOST_CHECK(framesWritten.size() == numFramesToTranslate);
+
+    for (FrameSeq::iterator iter = framesWritten.begin();
+            iter != framesWritten.end(); ++iter)
+    {
+        BOOST_CHECK(SignedLinearPtr::dynamicCast((*iter)->mediaFormat) != 0);
+
+        ShortSeqPayloadPtr payload = ShortSeqPayloadPtr::dynamicCast((*iter)->payload);
+
+        BOOST_REQUIRE(payload != 0);
+
+        AudioFormatPtr audio = AudioFormatPtr::dynamicCast((*iter)->mediaFormat);
+
+        BOOST_REQUIRE(audio != 0);
+
+        BOOST_CHECK((int) payload->payload.size() == audio->frameSize);
+    }
+}
+
+BOOST_FIXTURE_TEST_CASE(g722ToSlin16, PerTestFixture)
+{
+    size_t numFramesToTranslate = 10;
+
+    //For this test, we have to base the resultant frame on the size of the input frame.
+
+    Testbed.slin16->frameSize = Testbed.sampleSlin16FrameSize;
+
+    MediaOperationServiceLocatorParamsPtr g722ToSlinParams = createLocatorParams(Testbed.g722, Testbed.slin16);
+
+    MediaOperationFactoryPrx g722ToSlinFactory =
+        MediaOperationFactoryPrx::checkedCast(Testbed.locator->locate(g722ToSlinParams));
+
+    MediaOperationPrx g722ToSlinTranslator =
+        g722ToSlinFactory->createMediaOperation(Testbed.g722SourceProxy, Testbed.slin16SinkProxy);
+
+    StreamSinkPrx translatorSink = g722ToSlinTranslator->getSink();
+    StreamSourcePrx translatorSource = g722ToSlinTranslator->getSource();
+
+    Testbed.g722SourceProxy->addSink(translatorSink);
+    Testbed.slin16SinkProxy->setSource(translatorSource);
+
+    translatorSource->addSink(Testbed.slin16SinkProxy);
+    translatorSink->setSource(Testbed.g722SourceProxy);
+
+    FrameSeq g722Frames(numFramesToTranslate, Testbed.sampleG722Frame);
+
+    try
+    {
+        Testbed.g722Source->feedFramesToTranslator(g722Frames);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        std::stringstream str;
+        str << "Exception caught trying to translate G.722 frames: " << ex.what();
+        BOOST_FAIL(str.str());
+    }
+
+    FrameSeq framesWritten = Testbed.slin16Sink->getFrames();
+
+    BOOST_CHECK(framesWritten.size() == numFramesToTranslate);
+
+    for (FrameSeq::iterator iter = framesWritten.begin();
+            iter != framesWritten.end(); ++iter)
+    {
+        BOOST_CHECK(SignedLinearPtr::dynamicCast((*iter)->mediaFormat) != 0);
+
+        ShortSeqPayloadPtr payload = ShortSeqPayloadPtr::dynamicCast((*iter)->payload);
+
+        BOOST_REQUIRE(payload != 0);
+
+        AudioFormatPtr audio = AudioFormatPtr::dynamicCast((*iter)->mediaFormat);
+
+        BOOST_REQUIRE(audio != 0);
+
+        BOOST_CHECK((int) payload->payload.size() == audio->frameSize);
+    }
+}
+

commit 4c97dae294f9274d55f254596aee1428c4c3a413
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Aug 31 15:37:51 2011 -0500

    G.722 translator has been written now.
    
    Next step: tests!

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 75f6102..b7aee9c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -18,6 +18,9 @@ astscf_component_add_files(MediaOperationsCore resample.h)
 astscf_component_add_files(MediaOperationsCore resample.cpp)
 astscf_component_add_files(MediaOperationsCore g722.h)
 astscf_component_add_files(MediaOperationsCore g722.cpp)
+astscf_component_add_files(MediaOperationsCore g722/g722_encode.c)
+astscf_component_add_files(MediaOperationsCore g722/g722_decode.c)
+astscf_component_add_files(MediaOperationsCore g722/g722.h)
 astscf_component_add_files(MediaOperationsCore MediaOperationFactoryImpl.h)
 astscf_component_add_files(MediaOperationsCore MediaOperationFactoryImpl.cpp)
 astscf_component_add_files(MediaOperationsCore MediaOperationsCore.cpp)
diff --git a/src/MediaOperationsCore.cpp b/src/MediaOperationsCore.cpp
index e78218e..296d41b 100644
--- a/src/MediaOperationsCore.cpp
+++ b/src/MediaOperationsCore.cpp
@@ -25,6 +25,7 @@
 #include "MediaOperationFactoryImpl.h"
 #include "ulaw_alaw.h"
 #include "resample.h"
+#include "g722.h"
 
 using namespace AsteriskSCF::System::Logging;
 
@@ -190,6 +191,10 @@ private:
         lg(Debug) << "Creating Resampler";
         createAndRegisterFactory(new ResampleFactory(getServiceAdapter(), lg,
                     boost::static_pointer_cast<MediaOperationReplicationContext>(getReplicationContext())));
+
+        lg(Debug) << "Creating G.722 Factory";
+        createAndRegisterFactory(new G722Factory(getServiceAdapter(), lg,
+                    boost::static_pointer_cast<MediaOperationReplicationContext>(getReplicationContext())));
     }
 
     void locateStateReplicator()
diff --git a/src/g722.cpp b/src/g722.cpp
index 47cfb4b..7d60640 100644
--- a/src/g722.cpp
+++ b/src/g722.cpp
@@ -16,6 +16,8 @@
 
 #include <AsteriskSCF/Media/Formats/AudioFormats.h>
 
+#include "g722/g722.h"
+
 #include "g722.h"
 #include "TranslatorOperation.h"
 
@@ -42,13 +44,100 @@ private:
                 const Logger& logger)
             : Translator(source, inputFormat, outputFormat, logger)
         {
+            //XXX Do we have any intention of supporting 48 Kbps or
+            //56 Kbps G.722?
+            g722_encode_init(&mEncodeFromSlin8, 64000, G722_SAMPLE_RATE_8000);
+            g722_decode_init(&mDecodeToSlin8, 64000, G722_SAMPLE_RATE_8000);
+            g722_encode_init(&mEncodeFromSlin16, 64000, 0);
+            g722_decode_init(&mDecodeToSlin16, 64000, 0);
+        }
+
+        FramePtr translateFromG722(const FramePtr& inFrame)
+        {
+            AudioFormatPtr inFormat = AudioFormatPtr::dynamicCast(inFrame->mediaFormat);
+            AudioFormatPtr outFormat = AudioFormatPtr::dynamicCast(mOutputFormat);
+
+            ByteSeqPayloadPtr inPayload = ByteSeqPayloadPtr::dynamicCast(inFrame->payload);
+
+            if (!inPayload)
+            {
+                throw UnsupportedMediaFormatException();
+            }
+
+            int outsamples;
+            if (outFormat->name == SignedLinear16Name)
+            {
+                //Translating to slin16
+                outsamples = g722_decode(&mDecodeToSlin16, outbuffer16, &inPayload->payload.front(), inFormat->frameSize);
+            }
+            else
+            {
+                //Translating to slin8
+                outsamples = g722_decode(&mDecodeToSlin8, outbuffer16, &inPayload->payload.front(), inFormat->frameSize);
+            }
+
+            ShortSeqPayloadPtr outPayload(new ShortSeqPayload(Ice::ShortSeq(outsamples)));
+            outFormat->frameSize = outsamples;
+            return new Frame(outFormat, outPayload);
+        }
+
+        FramePtr translateToG722(const FramePtr& inFrame)
+        {
+            AudioFormatPtr inFormat = AudioFormatPtr::dynamicCast(inFrame->mediaFormat);
+            AudioFormatPtr outFormat = AudioFormatPtr::dynamicCast(mOutputFormat);
+
+            ShortSeqPayloadPtr inPayload = ShortSeqPayloadPtr::dynamicCast(inFrame->payload);
+
+            if (!inPayload)
+            {
+                throw UnsupportedMediaFormatException();
+            }
+
+            int outlen;
+            if (inFormat->name == SignedLinear16Name)
+            {
+                //Translating from slin16
+                outlen = g722_encode(&mEncodeFromSlin16, outbuffer8,  &inPayload->payload.front(), inFormat->frameSize);
+            }
+            else
+            {
+                //Translating from slin8
+                outlen = g722_encode(&mEncodeFromSlin8, outbuffer8, &inPayload->payload.front(), inFormat->frameSize);
+            }
+
+            ByteSeqPayloadPtr outPayload(new ByteSeqPayload(Ice::ByteSeq(outlen)));
+            outFormat->frameSize = outlen;
+            return new Frame(outFormat, outPayload);
         }
 
-        FramePtr translate(const FramePtr)
+        FramePtr translate(const FramePtr inFrame)
         {
-            //stub
-            return 0;
+            if (!TranslatorOperationFactory::formatsEqual1(inFrame->mediaFormat, mInputFormat))
+            {
+                mLogger(Error) << "Cannot translate frame because the format is not what we expect.";
+                throw UnsupportedMediaFormatException();
+            }
+
+            if (inFrame->mediaFormat->name == G722Name)
+            {
+                return translateFromG722(inFrame);
+            }
+            else
+            {
+                return translateToG722(inFrame);
+            }
         }
+    private:
+        g722_encode_state_t mEncodeFromSlin8;
+        g722_decode_state_t mDecodeToSlin8;
+        g722_encode_state_t mEncodeFromSlin16;
+        g722_decode_state_t mDecodeToSlin16;
+        //XXX Buffer sizes gotten from Asterisk.
+        //It's *highly* unlikely we need buffers this
+        //large since we aren't accumulating samples
+        //the same way that Asterisk's translators do.
+        uint8_t outbuffer8[8096];
+        int16_t outbuffer16[4048];
     };
 
 public:
diff --git a/src/ulaw_alaw.cpp b/src/ulaw_alaw.cpp
index b6aeded..2d3e2a9 100644
--- a/src/ulaw_alaw.cpp
+++ b/src/ulaw_alaw.cpp
@@ -75,11 +75,6 @@ private:
             FramePtr outFrame;
             Ice::ByteSeq outPayload;
         
-            //If we wanted to do things the "correct" way here, we'd call on the format
-            //operation in order to decode the frame payload and then re-encode it after
-            //we translated. But that amounts to way too many unnecessary RPCs. Since
-            //we know of the attributes of the formats, we'll do things the shortcut way.
-
             ByteSeqPayloadPtr inPayload = ByteSeqPayloadPtr::dynamicCast(inFrame->payload);
             if (!inPayload)
             {

commit e1a4d000a0583d47a360dc04cdb8cdf9b0e6e1b1
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Aug 31 09:52:56 2011 -0500

    Adjust the addTranslation method to take individual translations instead of multiple.
    
    I realized that the cost of translation could differ per translation, so they need
    to be added individually.

diff --git a/src/TranslatorOperationFactory.cpp b/src/TranslatorOperationFactory.cpp
index ba13657..bce48d7 100644
--- a/src/TranslatorOperationFactory.cpp
+++ b/src/TranslatorOperationFactory.cpp
@@ -95,28 +95,17 @@ MediaOperationPrx TranslatorOperationFactory::createMediaOperation(
 
 void TranslatorOperationFactory::addTranslation(
         const FormatPtr& inFormat,
-        const FormatSeq& outFormats,
+        const FormatPtr& outFormat,
         int cost)
 {
-    std::pair<TranslationMap::iterator, bool> inserted =
-        mTranslations.insert(std::make_pair(inFormat->name, outFormats));
+    mTranslations[inFormat->name].push_back(outFormat);
 
-    if (inserted.second == false)
-    {
-        mLogger(Error) << "There was an error trying to add a translation to the factory?";
-        return;
-    }
+    MediaOperationAttributes attrs;
+    attrs.inputFormat = inFormat;
+    attrs.outputFormat = outFormat;
+    attrs.cost = cost;
 
-    for (FormatSeq::iterator iter = inserted.first->second.begin();
-            iter != inserted.first->second.end(); ++iter)
-    {
-        MediaOperationAttributes attrs;
-        attrs.inputFormat = inFormat;
-        attrs.outputFormat = *iter;
-        attrs.cost = cost;
-
-        mLocatorParams->attributes.push_back(attrs);
-    }
+    mLocatorParams->attributes.push_back(attrs);
 }
 
 bool TranslatorOperationFactory::formatsEqual1(
diff --git a/src/TranslatorOperationFactory.h b/src/TranslatorOperationFactory.h
index 50cdb9a..d95389f 100644
--- a/src/TranslatorOperationFactory.h
+++ b/src/TranslatorOperationFactory.h
@@ -46,7 +46,7 @@ public:
 
     void addTranslation(
             const AsteriskSCF::Media::V1::FormatPtr&,
-            const AsteriskSCF::Media::V1::FormatSeq&,
+            const AsteriskSCF::Media::V1::FormatPtr&,
             int cost);
 
     static bool formatsEqual1(
diff --git a/src/g722.cpp b/src/g722.cpp
index a1b9a20..47cfb4b 100644
--- a/src/g722.cpp
+++ b/src/g722.cpp
@@ -111,16 +111,10 @@ void G722Factory::buildTranslations()
     FormatPtr g722 = new G722();
     g722->name = G722Name;
 
-    FormatSeq slins;
-    slins.push_back(slin8);
-    slins.push_back(slin16);
-
-    FormatSeq g722Seq;
-    g722Seq.push_back(g722);
-
-    addTranslation(g722, slins, 100);
-    addTranslation(slin8, g722Seq, 100);
-    addTranslation(slin16, g722Seq, 100);
+    addTranslation(g722, slin8, 100);
+    addTranslation(g722, slin16, 100);
+    addTranslation(slin8, g722, 100);
+    addTranslation(slin16, g722, 100);
 }
 
 } //end namespace MediaOperationsCore
diff --git a/src/resample.cpp b/src/resample.cpp
index d7b36b6..de4cb64 100644
--- a/src/resample.cpp
+++ b/src/resample.cpp
@@ -182,14 +182,8 @@ void ResampleFactory::buildTranslations()
     FormatPtr slin16 = new SignedLinear();
     slin16->name = SignedLinear16Name;
 
-    FormatSeq slin8Seq;
-    slin8Seq.push_back(slin8);
-
-    FormatSeq slin16Seq;
-    slin16Seq.push_back(slin16);
-
-    addTranslation(slin8, slin16Seq, 100);
-    addTranslation(slin16, slin8Seq, 100);
+    addTranslation(slin8, slin16, 100);
+    addTranslation(slin16, slin8, 100);
 }
 
 }
diff --git a/src/ulaw_alaw.cpp b/src/ulaw_alaw.cpp
index 13141ab..b6aeded 100644
--- a/src/ulaw_alaw.cpp
+++ b/src/ulaw_alaw.cpp
@@ -139,14 +139,8 @@ void UlawAlawFactory::buildTranslations()
     FormatPtr alaw = new G711aLAW();
     alaw->name = G711aLAWName;
 
-    FormatSeq ulawSeq;
-    ulawSeq.push_back(ulaw);
-
-    FormatSeq alawSeq;
-    alawSeq.push_back(alaw);
-
-    addTranslation(ulaw, alawSeq, 100);
-    addTranslation(alaw, ulawSeq, 100);
+    addTranslation(ulaw, alaw, 100);
+    addTranslation(alaw, ulaw, 100);
 }
 
 MediaOperationPrx UlawAlawFactory::createMediaOperation(

commit 8f268ab4640dd61173cc2b79516cd8723476ee3d
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Aug 30 17:28:31 2011 -0500

    Add g722 operation file.
    
    The translator is just stubbed out for the moment.

diff --git a/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice b/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
index 02a4f63..313bc60 100644
--- a/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
+++ b/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
@@ -99,6 +99,13 @@ class ResamplerMediaOperationStateItem extends TranslatorMediaOperationStateItem
 {
 };
 
+/**
+ * State item for G722 translators
+ */
+class G722MediaOperationStateItem extends TranslatorMediaOperationStateItem
+{
+};
+
 interface MediaOperationStateReplicatorListener
 {
     void stateRemoved(Ice::StringSeq itemKeys);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e4b02f7..75f6102 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -16,6 +16,8 @@ astscf_component_add_files(MediaOperationsCore ulaw_alaw.h)
 astscf_component_add_files(MediaOperationsCore ulaw_alaw.cpp)
 astscf_component_add_files(MediaOperationsCore resample.h)
 astscf_component_add_files(MediaOperationsCore resample.cpp)
+astscf_component_add_files(MediaOperationsCore g722.h)
+astscf_component_add_files(MediaOperationsCore g722.cpp)
 astscf_component_add_files(MediaOperationsCore MediaOperationFactoryImpl.h)
 astscf_component_add_files(MediaOperationsCore MediaOperationFactoryImpl.cpp)
 astscf_component_add_files(MediaOperationsCore MediaOperationsCore.cpp)
diff --git a/src/g722.cpp b/src/g722.cpp
new file mode 100644
index 0000000..a1b9a20
--- /dev/null
+++ b/src/g722.cpp
@@ -0,0 +1,127 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, 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 <AsteriskSCF/Media/Formats/AudioFormats.h>
+
+#include "g722.h"
+#include "TranslatorOperation.h"
+
+namespace AsteriskSCF
+{
+
+namespace MediaOperationsCore
+{
+
+using namespace AsteriskSCF::Media::V1;
+using namespace AsteriskSCF::Media::Formats::Audio::V1;
+using namespace AsteriskSCF::System::Logging;
+using namespace AsteriskSCF::Replication::MediaOperationsCore::V1;
+
+class G722Operation : public TranslatorOperation
+{
+private:
+    class G722Translator : public Translator
+    {
+    public:
+        G722Translator (const TranslatorSourcePtr& source,
+                const FormatPtr& inputFormat,
+                const FormatPtr& outputFormat,
+                const Logger& logger)
+            : Translator(source, inputFormat, outputFormat, logger)
+        {
+        }
+
+        FramePtr translate(const FramePtr)
+        {
+            //stub
+            return 0;
+        }
+    };
+
+public:
+    G722Operation(const Ice::ObjectAdapterPtr& adapter,
+            const Logger& logger,
+            const FormatPtr& sourceFormat,
+            const FormatPtr& sinkFormat,
+            const Ice::Identity& factoryId,
+            const MediaOperationReplicationContextPtr& replicationContext)
+        : TranslatorOperation(
+                adapter,
+                logger,
+                sourceFormat,
+                sinkFormat,
+                factoryId,
+                replicationContext,
+                new G722MediaOperationStateItem)
+    {
+        mSink->setTranslator(new G722Translator(mSource, sinkFormat, sourceFormat, mLogger));
+    }
+};
+
+typedef IceUtil::Handle<G722Operation> G722OperationPtr;
+
+G722Factory::G722Factory(
+        const Ice::ObjectAdapterPtr& adapter,
+        const Logger& logger,
+        const MediaOperationReplicationContextPtr& replicationContext)
+    : TranslatorOperationFactory(adapter, logger, replicationContext, "G722Factory")
+{
+    buildTranslations();
+}
+
+MediaOperationPrx G722Factory::createMediaOperation(
+        const FormatPtr& sourceFormat,
+        const FormatPtr& sinkFormat,
+        const std::string& operationId)
+{
+    G722OperationPtr operation(
+            new G722Operation(
+                mAdapter,
+                mLogger,
+                sourceFormat,
+                sinkFormat,
+                getProxy()->ice_getIdentity(),
+                mReplicationContext));
+
+    MediaOperationPrx proxy = operation->activate(operationId);
+    return proxy;
+}
+
+void G722Factory::buildTranslations()
+{
+    FormatPtr slin8 = new SignedLinear();
+    slin8->name = SignedLinear8Name;
+
+    FormatPtr slin16 = new SignedLinear();
+    slin16->name = SignedLinear16Name;
+
+    FormatPtr g722 = new G722();
+    g722->name = G722Name;
+
+    FormatSeq slins;
+    slins.push_back(slin8);
+    slins.push_back(slin16);
+
+    FormatSeq g722Seq;
+    g722Seq.push_back(g722);
+
+    addTranslation(g722, slins, 100);
+    addTranslation(slin8, g722Seq, 100);
+    addTranslation(slin16, g722Seq, 100);
+}
+
+} //end namespace MediaOperationsCore
+} //end namespace AsteriskSCF
diff --git a/src/g722.h b/src/g722.h
new file mode 100644
index 0000000..801af1c
--- /dev/null
+++ b/src/g722.h
@@ -0,0 +1,44 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, 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
+
+#include "TranslatorOperationFactory.h"
+
+namespace AsteriskSCF
+{
+
+namespace MediaOperationsCore
+{
+
+class G722Factory : public TranslatorOperationFactory
+{
+public:
+    G722Factory(const Ice::ObjectAdapterPtr&,
+            const AsteriskSCF::System::Logging::Logger& logger,
+            const MediaOperationReplicationContextPtr& replicationContext);
+
+    AsteriskSCF::Media::V1::MediaOperationPrx createMediaOperation(
+            const AsteriskSCF::Media::V1::FormatPtr& sourceFormat,
+            const AsteriskSCF::Media::V1::FormatPtr& sinkFormat,
+            const std::string& operationId);
+private:
+    void buildTranslations();
+};
+
+typedef IceUtil::Handle<G722Factory> G722FactoryPtr;
+
+} //end namespace MediaOperationsCore
+} //end namespace AsteriskSCF

commit d3f7b508acf663660231a637a67360f9f2d37be5
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Aug 30 16:53:46 2011 -0500

    Create a common TranslatorOperation class and convert resampler and ulaw_alaw to use it.

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4de238e..e4b02f7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,6 +10,8 @@ astscf_component_add_files(MediaOperationsCore TranslatorSource.cpp)
 astscf_component_add_files(MediaOperationsCore TranslatorSource.h)
 astscf_component_add_files(MediaOperationsCore TranslatorOperationFactory.cpp)
 astscf_component_add_files(MediaOperationsCore TranslatorOperationFactory.h)
+astscf_component_add_files(MediaOperationsCore TranslatorOperation.cpp)
+astscf_component_add_files(MediaOperationsCore TranslatorOperation.h)
 astscf_component_add_files(MediaOperationsCore ulaw_alaw.h)
 astscf_component_add_files(MediaOperationsCore ulaw_alaw.cpp)
 astscf_component_add_files(MediaOperationsCore resample.h)
diff --git a/src/TranslatorOperation.cpp b/src/TranslatorOperation.cpp
new file mode 100644
index 0000000..078016a
--- /dev/null
+++ b/src/TranslatorOperation.cpp
@@ -0,0 +1,140 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, 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 "TranslatorOperation.h"
+
+namespace AsteriskSCF
+{
+
+namespace MediaOperationsCore
+{
+
+using namespace AsteriskSCF::System::Logging;
+using namespace AsteriskSCF::Media::V1;
+using namespace AsteriskSCF::Replication::MediaOperationsCore::V1;
+
+TranslatorOperation::TranslatorOperation(const Ice::ObjectAdapterPtr& adapter,
+        const Logger& logger,
+        const FormatPtr& sourceFormat,
+        const FormatPtr& sinkFormat,
+        const Ice::Identity& factoryId,
+        const MediaOperationReplicationContextPtr& replicationContext,
+        const TranslatorMediaOperationStateItemPtr& stateItem)
+    : mAdapter(adapter),
+    mLogger(logger),
+    mSource(new TranslatorSource(mLogger, sourceFormat)),
+    mSink(new TranslatorSink(mLogger, sinkFormat)),
+    mReplicationContext(replicationContext),
+    mStateItem(stateItem)
+{
+    mStateItem->sourceFormat = sourceFormat;
+    mStateItem->sinkFormat = sinkFormat;
+    mStateItem->factoryId = factoryId;
+}
+
+TranslatorOperation::~TranslatorOperation()
+{
+    mLogger(Debug) << "UlawAlawOperation destructor called";
+
+    try
+    {
+        mAdapter->remove(mSourceProxy->ice_getIdentity());
+        mAdapter->remove(mSinkProxy->ice_getIdentity());
+    }
+    catch (const Ice::Exception& ex)
+    {
+        mLogger(Error) << "Exception caught while trying to remove source and sink from object adapter";
+    }
+}
+
+void TranslatorOperation::setState()
+{
+    if (mReplicationContext->isReplicating() == false)
+    {
+        return;
+    }
+
+    try
+    {
+        MediaOperationStateItemSeq seq;
+        seq.push_back(mStateItem);
+        mReplicationContext->getReplicator().tryOneWay()->setState(seq);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        mLogger(Error) << "Exception caught while attempting to replicate state: " << ex.what();
+    }
+}
+
+void TranslatorOperation::removeState()
+{
+    if (mReplicationContext->isReplicating() == false)
+    {
+        return;
+    }
+
+    try
+    {
+        MediaOperationStateItemSeq seq;
+        seq.push_back(mStateItem);
+        mReplicationContext->getReplicator().tryOneWay()->removeStateForItems(seq);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        mLogger(Error) << "Exception caught while attempting to replicate state: " << ex.what();
+    }
+}
+
+MediaOperationPrx TranslatorOperation::activate(const std::string& id)
+{
+    mProxy =
+        MediaOperationPrx::uncheckedCast(mAdapter->add(this, mAdapter->getCommunicator()->stringToIdentity(id)));
+    mSinkProxy =
+        StreamSinkPrx::uncheckedCast(mAdapter->add(mSink, mAdapter->getCommunicator()->stringToIdentity(id + ".Sink")));
+    mSourceProxy =
+        StreamSourcePrx::uncheckedCast(mAdapter->add(mSource, mAdapter->getCommunicator()->stringToIdentity(id +".Source")));
+
+    mStateItem->operationId = mProxy->ice_getIdentity().name;
+
+    setState();
+
+    return mProxy;
+}
+
+StreamSourcePrx TranslatorOperation::getSource(const Ice::Current&)
+{
+    return mSourceProxy;
+}
+
+StreamSinkPrx TranslatorOperation::getSink(const Ice::Current&)
+{
+    return mSinkProxy;
+}
+
+void TranslatorOperation::destroy(const Ice::Current&)
+{
+    try
+    {
+        mAdapter->remove(mProxy->ice_getIdentity());
+    }
+    catch (Ice::Exception& ex)
+    {
+        mLogger(Error) << "Exception caught attempting to remove media operation from adapter: " << ex.what();
+    }
+}
+
+}
+}
diff --git a/src/TranslatorOperation.h b/src/TranslatorOperation.h
new file mode 100644
index 0000000..bb9f4c7
--- /dev/null
+++ b/src/TranslatorOperation.h
@@ -0,0 +1,71 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, 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
+
+#include <AsteriskSCF/Media/MediaOperationIf.h>
+#include <AsteriskSCF/logger.h>
+#include <AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.h>
+
+#include "TranslatorSink.h"
+#include "TranslatorSource.h"
+#include "MediaOperationReplicationContext.h"
+
+namespace AsteriskSCF
+{
+
+namespace MediaOperationsCore
+{
+
+class TranslatorOperation : public AsteriskSCF::Media::V1::MediaOperation
+{
+public:
+    TranslatorOperation(const Ice::ObjectAdapterPtr& adapter,
+            const AsteriskSCF::System::Logging::Logger& logger,
+            const AsteriskSCF::Media::V1::FormatPtr& sourceFormat,
+            const AsteriskSCF::Media::V1::FormatPtr& sinkFormat,
+            const Ice::Identity& factoryId,
+            const MediaOperationReplicationContextPtr& replicationContext,
+            const AsteriskSCF::Replication::MediaOperationsCore::V1::TranslatorMediaOperationStateItemPtr& stateItem);
+
+    virtual ~TranslatorOperation();
+
+    virtual void setState();
+
+    virtual void removeState();
+
+    virtual AsteriskSCF::Media::V1::MediaOperationPrx activate(const std::string& id);
+
+    virtual void destroy(const Ice::Current&);
+
+    AsteriskSCF::Media::V1::StreamSourcePrx getSource(const Ice::Current&);
+
+    AsteriskSCF::Media::V1::StreamSinkPrx getSink(const Ice::Current&);
+    
+protected:
+    Ice::ObjectAdapterPtr mAdapter;
+    AsteriskSCF::System::Logging::Logger mLogger;
+    AsteriskSCF::Media::V1::MediaOperationPrx mProxy;
+    TranslatorSourcePtr mSource;
+    AsteriskSCF::Media::V1::StreamSourcePrx mSourceProxy;
+    TranslatorSinkPtr mSink;
+    AsteriskSCF::Media::V1::StreamSinkPrx mSinkProxy;
+    MediaOperationReplicationContextPtr mReplicationContext;
+    AsteriskSCF::Replication::MediaOperationsCore::V1::TranslatorMediaOperationStateItemPtr mStateItem;
+};
+
+}
+}
diff --git a/src/TranslatorSink.cpp b/src/TranslatorSink.cpp
index 25bf231..81719b4 100644
--- a/src/TranslatorSink.cpp
+++ b/src/TranslatorSink.cpp
@@ -28,11 +28,9 @@ using namespace AsteriskSCF::Media::V1;
 using namespace AsteriskSCF::System::Logging;
 
 TranslatorSink::TranslatorSink(const Logger& logger,
-        const FormatPtr& supportedFormat,
-        const TranslatorPtr& translator)
+        const FormatPtr& supportedFormat)
     : mLogger(logger),
-    mId(IceUtil::generateUUID()),
-    mTranslator(translator)
+    mId(IceUtil::generateUUID())
 {
     mSupportedFormats.push_back(supportedFormat);
 }
@@ -47,6 +45,11 @@ void TranslatorSink::write(const FrameSeq& frames, const Ice::Current&)
     mTranslator->translateFrames(frames);
 }
 
+void TranslatorSink::setTranslator(const TranslatorPtr& translator)
+{
+    mTranslator = translator;
+}
+
 void TranslatorSink::setSource(const StreamSourcePrx& source, const Ice::Current&)
 {
     mSource = source;
diff --git a/src/TranslatorSink.h b/src/TranslatorSink.h
index fa5bee5..80b07db 100644
--- a/src/TranslatorSink.h
+++ b/src/TranslatorSink.h
@@ -31,13 +31,14 @@ class TranslatorSink : public AsteriskSCF::Media::V1::StreamSink
 {
 public:
     TranslatorSink(const AsteriskSCF::System::Logging::Logger& logger,
-            const AsteriskSCF::Media::V1::FormatPtr& supportedFormat,
-            const TranslatorPtr& translator);
+            const AsteriskSCF::Media::V1::FormatPtr& supportedFormat);
 
     ~TranslatorSink();
     
     void write(const AsteriskSCF::Media::V1::FrameSeq& frames, const Ice::Current&);
 
+    void setTranslator(const TranslatorPtr& translator);
+
     void setSource(const AsteriskSCF::Media::V1::StreamSourcePrx& source, const Ice::Current&);
 
     AsteriskSCF::Media::V1::StreamSourcePrx getSource(const Ice::Current&);
diff --git a/src/resample.cpp b/src/resample.cpp
index 9be11ac..d7b36b6 100644
--- a/src/resample.cpp
+++ b/src/resample.cpp
@@ -22,6 +22,7 @@
 #include "TranslatorSource.h"
 #include "Translator.h"
 #include "TranslatorSink.h"
+#include "TranslatorOperation.h"
 
 using namespace AsteriskSCF::Media::V1;
 
@@ -46,7 +47,7 @@ using namespace AsteriskSCF::Media::Formats::Audio::V1;
 using namespace AsteriskSCF::System::Logging;
 using namespace AsteriskSCF::Replication::MediaOperationsCore::V1;
 
-class ResampleOperation : public MediaOperation
+class ResampleOperation : public TranslatorOperation
 {
 private:
     class Resampler : public Translator
@@ -128,121 +129,17 @@ public:
             const Ice::Identity& factoryId,
             const MediaOperationReplicationContextPtr& replicationContext,
             pj_caching_pool *cachingPool)
-        : mAdapter(adapter),
-        mLogger(logger),
-        mStateItem(new ResamplerMediaOperationStateItem),
-        mSource(new TranslatorSource(mLogger, sourceFormat)),
-        mSink(new TranslatorSink(mLogger, sinkFormat, new Resampler(mSource, sinkFormat, sourceFormat, mLogger, cachingPool))),
-        mReplicationContext(replicationContext)
-    {
-        mStateItem->sourceFormat = sourceFormat;
-        mStateItem->sinkFormat = sinkFormat;
-        mStateItem->factoryId = factoryId;
-    }
-
-    //XXX Almost all of this is copied and pasted from the ulaw<->alaw translator.
-    //This should probably extracted into a base class...
-    ~ResampleOperation()
-    {
-        mLogger(Debug) << "ResampleOperation destructor called";
-
-        try
-        {
-            mAdapter->remove(mSourceProxy->ice_getIdentity());
-            mAdapter->remove(mSinkProxy->ice_getIdentity());
-        }
-        catch (const Ice::Exception& ex)
-        {
-            mLogger(Error) << "Exception caught while trying to remove source and sink from object adapter";
-        }
-    }
-
-    void setState()
-    {
-        if (mReplicationContext->isReplicating() == false)
-        {
-            return;
-        }
-
-        try
-        {
-            MediaOperationStateItemSeq seq;
-            seq.push_back(mStateItem);
-            mReplicationContext->getReplicator().tryOneWay()->setState(seq);
-        }
-        catch (const Ice::Exception& ex)
-        {
-            mLogger(Error) << "Exception caught while attempting to replicate state: " << ex.what();
-        }
-    }
-
-    void removeState()
-    {
-        if (mReplicationContext->isReplicating() == false)
-        {
-            return;
-        }
-
-        try
-        {
-            MediaOperationStateItemSeq seq;
-            seq.push_back(mStateItem);
-            mReplicationContext->getReplicator().tryOneWay()->removeStateForItems(seq);
-        }
-        catch (const Ice::Exception& ex)
-        {
-            mLogger(Error) << "Exception caught while attempting to replicate state: " << ex.what();
-        }
-    }
-
-    MediaOperationPrx activate(const std::string& id)
-    {
-        mProxy =
-            MediaOperationPrx::uncheckedCast(mAdapter->add(this, mAdapter->getCommunicator()->stringToIdentity(id)));
-        mSinkProxy =
-            StreamSinkPrx::uncheckedCast(mAdapter->add(mSink, mAdapter->getCommunicator()->stringToIdentity(id + ".Sink")));
-        mSourceProxy =
-            StreamSourcePrx::uncheckedCast(mAdapter->add(mSource, mAdapter->getCommunicator()->stringToIdentity(id +".Source")));
-
-        mStateItem->operationId = mProxy->ice_getIdentity().name;
-
-        setState();
-
-        return mProxy;
-    }
-
-    StreamSourcePrx getSource(const Ice::Current&)
-    {
-        return mSourceProxy;
-    }
-
-    StreamSinkPrx getSink(const Ice::Current&)
-    {
-        return mSinkProxy;
-    }
-
-    void destroy(const Ice::Current&)
+        : TranslatorOperation(
+                adapter,
+                logger,
+                sourceFormat,
+                sinkFormat,
+                factoryId,
+                replicationContext,
+                new ResamplerMediaOperationStateItem)
     {
-        try
-        {
-            mAdapter->remove(mProxy->ice_getIdentity());
-        }
-        catch (Ice::Exception& ex)
-        {
-            mLogger(Error) << "Exception caught attempting to remove media operation from adapter: " << ex.what();
-        }
+        mSink->setTranslator(new Resampler(mSource, sinkFormat, sourceFormat, mLogger, cachingPool));
     }
-
-private:
-    Ice::ObjectAdapterPtr mAdapter;
-    Logger mLogger;
-    MediaOperationPrx mProxy;
-    ResamplerMediaOperationStateItemPtr mStateItem;
-    TranslatorSourcePtr mSource;
-    StreamSourcePrx mSourceProxy;
-    TranslatorSinkPtr mSink;
-    StreamSinkPrx mSinkProxy;
-    MediaOperationReplicationContextPtr mReplicationContext;
 };
 
 typedef IceUtil::Handle<ResampleOperation> ResampleOperationPtr;
diff --git a/src/ulaw_alaw.cpp b/src/ulaw_alaw.cpp
index b7f944e..13141ab 100644
--- a/src/ulaw_alaw.cpp
+++ b/src/ulaw_alaw.cpp
@@ -23,6 +23,7 @@
 #include "TranslatorSource.h"
 #include "Translator.h"
 #include "TranslatorSink.h"
+#include "TranslatorOperation.h"
 
 namespace AsteriskSCF
 {
@@ -36,7 +37,7 @@ using namespace AsteriskSCF::Media::Formats::Audio::V1;
 using namespace AsteriskSCF::System::Logging;
 using namespace AsteriskSCF::Replication::MediaOperationsCore::V1;
 
-class UlawAlawOperation : public MediaOperation
+class UlawAlawOperation : public TranslatorOperation
 {
 private:
     class UlawAlawTranslator : public Translator
@@ -107,119 +108,17 @@ public:
             const FormatPtr& sinkFormat,
             const Ice::Identity& factoryId,
             const MediaOperationReplicationContextPtr& replicationContext)
-        : mAdapter(adapter),
-        mLogger(logger),
-        mStateItem(new UlawAlawMediaOperationStateItem),
-        mSource(new TranslatorSource(mLogger, sourceFormat)),
-        mSink(new TranslatorSink(mLogger, sinkFormat, new UlawAlawTranslator(mSource, sinkFormat, sourceFormat, mLogger))),
-        mReplicationContext(replicationContext)
-    {
-        mStateItem->sourceFormat = sourceFormat;
-        mStateItem->sinkFormat = sinkFormat;
-        mStateItem->factoryId = factoryId;
-    }
-
-    ~UlawAlawOperation()
-    {
-        mLogger(Debug) << "UlawAlawOperation destructor called";
-
-        try
-        {
-            mAdapter->remove(mSourceProxy->ice_getIdentity());
-            mAdapter->remove(mSinkProxy->ice_getIdentity());
-        }
-        catch (const Ice::Exception& ex)
-        {
-            mLogger(Error) << "Exception caught while trying to remove source and sink from object adapter";
-        }
-    }
-
-    void setState()
-    {
-        if (mReplicationContext->isReplicating() == false)
-        {
-            return;
-        }
-
-        try
-        {
-            MediaOperationStateItemSeq seq;
-            seq.push_back(mStateItem);
-            mReplicationContext->getReplicator().tryOneWay()->setState(seq);
-        }
-        catch (const Ice::Exception& ex)
-        {
-            mLogger(Error) << "Exception caught while attempting to replicate state: " << ex.what();
-        }
-    }
-
-    void removeState()
-    {
-        if (mReplicationContext->isReplicating() == false)
-        {
-            return;
-        }
-
-        try
-        {
-            MediaOperationStateItemSeq seq;
-            seq.push_back(mStateItem);
-            mReplicationContext->getReplicator().tryOneWay()->removeStateForItems(seq);
-        }
-        catch (const Ice::Exception& ex)
-        {
-            mLogger(Error) << "Exception caught while attempting to replicate state: " << ex.what();
-        }
-    }
-
-    MediaOperationPrx activate(const std::string& id)
-    {
-        mProxy =
-            MediaOperationPrx::uncheckedCast(mAdapter->add(this, mAdapter->getCommunicator()->stringToIdentity(id)));
-        mSinkProxy =
-            StreamSinkPrx::uncheckedCast(mAdapter->add(mSink, mAdapter->getCommunicator()->stringToIdentity(id + ".Sink")));
-        mSourceProxy =
-            StreamSourcePrx::uncheckedCast(mAdapter->add(mSource, mAdapter->getCommunicator()->stringToIdentity(id +".Source")));
-
-        mStateItem->operationId = mProxy->ice_getIdentity().name;
-
-        setState();
-
-        return mProxy;
-    }
-
-    StreamSourcePrx getSource(const Ice::Current&)
-    {
-        return mSourceProxy;
-    }
-
-    StreamSinkPrx getSink(const Ice::Current&)
-    {
-        return mSinkProxy;
-    }
-
-    void destroy(const Ice::Current&)
+        : TranslatorOperation(
+                adapter,
+                logger,
+                sourceFormat,
+                sinkFormat,
+                factoryId,
+                replicationContext,
+                new UlawAlawMediaOperationStateItem)
     {
-        try
-        {
-            mAdapter->remove(mProxy->ice_getIdentity());
-        }
-        catch (Ice::Exception& ex)
-        {
-            mLogger(Error) << "Exception caught attempting to remove media operation from adapter: " << ex.what();
-        }
+        mSink->setTranslator(new UlawAlawTranslator(mSource, sinkFormat, sourceFormat, mLogger));
     }
-
-private:
-    Ice::ObjectAdapterPtr mAdapter;
-    Logger mLogger;
-    MediaOperationPrx mProxy;
-    UlawAlawMediaOperationStateItemPtr mStateItem;
-    TranslatorSourcePtr mSource;
-    StreamSourcePrx mSourceProxy;
-    TranslatorSinkPtr mSink;
-    StreamSinkPrx mSinkProxy;
-    MediaOperationReplicationContextPtr mReplicationContext;
 };
 
 typedef IceUtil::Handle<UlawAlawOperation> UlawAlawOperationPtr;

commit 306b4e7333135cdbf119f4fafae4f18e1121a72f
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Aug 30 14:47:07 2011 -0500

    Create a common translator factory class and make the resampler and ulaw<->alaw translator use it.

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 60673b9..4de238e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,18 +2,20 @@ include_directories(${logger_dir}/include)
 include_directories(${astscf-ice-util-cpp_dir}/include)
 
 astscf_component_init(MediaOperationsCore)
-astscf_component_add_files(MediaOperationsCore ulaw_alaw.h)
-astscf_component_add_files(MediaOperationsCore ulaw_alaw.cpp)
-astscf_component_add_files(MediaOperationsCore resample.h)
-astscf_component_add_files(MediaOperationsCore resample.cpp)
-astscf_component_add_files(MediaOperationsCore MediaOperationFactoryImpl.h)
-astscf_component_add_files(MediaOperationsCore MediaOperationFactoryImpl.cpp)
 astscf_component_add_files(MediaOperationsCore Translator.cpp)
 astscf_component_add_files(MediaOperationsCore Translator.h)
 astscf_component_add_files(MediaOperationsCore TranslatorSink.cpp)
 astscf_component_add_files(MediaOperationsCore TranslatorSink.h)
 astscf_component_add_files(MediaOperationsCore TranslatorSource.cpp)
 astscf_component_add_files(MediaOperationsCore TranslatorSource.h)
+astscf_component_add_files(MediaOperationsCore TranslatorOperationFactory.cpp)
+astscf_component_add_files(MediaOperationsCore TranslatorOperationFactory.h)
+astscf_component_add_files(MediaOperationsCore ulaw_alaw.h)
+astscf_component_add_files(MediaOperationsCore ulaw_alaw.cpp)
+astscf_component_add_files(MediaOperationsCore resample.h)
+astscf_component_add_files(MediaOperationsCore resample.cpp)
+astscf_component_add_files(MediaOperationsCore MediaOperationFactoryImpl.h)
+astscf_component_add_files(MediaOperationsCore MediaOperationFactoryImpl.cpp)
 astscf_component_add_files(MediaOperationsCore MediaOperationsCore.cpp)
 astscf_component_add_files(MediaOperationsCore MediaOperationStateReplicatorListener.cpp)
 astscf_component_add_files(MediaOperationsCore MediaOperationReplicationContext.h)
diff --git a/src/TranslatorOperationFactory.cpp b/src/TranslatorOperationFactory.cpp
new file mode 100644
index 0000000..ba13657
--- /dev/null
+++ b/src/TranslatorOperationFactory.cpp
@@ -0,0 +1,137 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, 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 <IceUtil/UUID.h>
+
+#include "TranslatorOperationFactory.h"
+
+namespace AsteriskSCF
+{
+
+namespace MediaOperationsCore
+{
+
+using namespace AsteriskSCF::Media::V1;
+using namespace AsteriskSCF::System::Logging;
+
+TranslatorOperationFactory::TranslatorOperationFactory(
+        const Ice::ObjectAdapterPtr& adapter,
+        const Logger& logger,
+        const MediaOperationReplicationContextPtr& replicationContext,
+        const std::string& name)
+    : MediaOperationFactoryImpl(adapter, logger, replicationContext, name)
+{
+    mLocatorParams->category = MediaOperationDiscoveryCategory;
+    mLocatorParams->service = MediaOperationDiscoveryTranslatorService;
+}
+
+MediaOperationPrx TranslatorOperationFactory::createMediaOperation(
+        const StreamSourcePrx& source,
+        const StreamSinkPrx& sink,
+        const Ice::Current&)
+{
+    if (sink == 0 || source == 0)
+    {
+        mLogger(Error) << "Cannot create translator because of a missing source or sink";
+        throw UnsupportedMediaFormatException();
+    }
+
+    FormatSeq sourceFormats = source->getFormats();
+    FormatSeq sinkFormats = sink->getFormats();
+
+    FormatSeq::iterator supportedInput = std::find_first_of(sourceFormats.begin(),
+            sourceFormats.end(),
+            mTranslations.begin(),
+            mTranslations.end(),
+            TranslatorOperationFactory::formatsEqual2);
+
+    if (supportedInput == sourceFormats.end())
+    {
+        mLogger(Error) << "Cannot create translator because none of the stream source's formats are supported";
+        throw UnsupportedMediaFormatException();
+    }
+
+    mLogger(Debug) << "When creating media operation, the input is " << (*supportedInput)->name;
+
+    for (FormatSeq::iterator iter = mTranslations[(*supportedInput)->name].begin();
+            iter != mTranslations[(*supportedInput)->name].end(); ++iter)
+    {
+        mLogger(Debug) << (*supportedInput)->name << " can be translated to " << (*iter)->name;
+    }
+
+    FormatSeq::iterator supportedOutput = std::find_first_of(sinkFormats.begin(),
+            sinkFormats.end(),
+            mTranslations[(*supportedInput)->name].begin(),
+            mTranslations[(*supportedInput)->name].end(),
+            TranslatorOperationFactory::formatsEqual1);
+
+    if (supportedOutput == sinkFormats.end())
+    {
+        mLogger(Error) << "Cannot create translator because none of the stream sink's formats are supported";
+        throw UnsupportedMediaFormatException();
+    }
+
+    mLogger(Debug) << "Creating a translator from " << (*supportedInput)->name
+        << " to " << (*supportedOutput)->name;
+
+    return createMediaOperation(
+            *supportedOutput,
+            *supportedInput,
+            IceUtil::generateUUID());
+}
+
+void TranslatorOperationFactory::addTranslation(
+        const FormatPtr& inFormat,
+        const FormatSeq& outFormats,
+        int cost)
+{
+    std::pair<TranslationMap::iterator, bool> inserted =
+        mTranslations.insert(std::make_pair(inFormat->name, outFormats));
+
+    if (inserted.second == false)
+    {
+        mLogger(Error) << "There was an error trying to add a translation to the factory?";
+        return;
+    }
+
+    for (FormatSeq::iterator iter = inserted.first->second.begin();
+            iter != inserted.first->second.end(); ++iter)
+    {
+        MediaOperationAttributes attrs;
+        attrs.inputFormat = inFormat;
+        attrs.outputFormat = *iter;
+        attrs.cost = cost;
+
+        mLocatorParams->attributes.push_back(attrs);
+    }
+}
+
+bool TranslatorOperationFactory::formatsEqual1(
+        const FormatPtr& lhs,
+        const FormatPtr& rhs)
+{
+    return lhs->name == rhs->name;
+}
+
+bool TranslatorOperationFactory::formatsEqual2(
+        const FormatPtr& lhs,
+        const std::pair<std::string, FormatSeq>& rhs)
+{
+    return lhs->name == rhs.first;
+}
+
+}
+}
diff --git a/src/TranslatorOperationFactory.h b/src/TranslatorOperationFactory.h
new file mode 100644
index 0000000..50cdb9a
--- /dev/null
+++ b/src/TranslatorOperationFactory.h
@@ -0,0 +1,69 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, 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
+
+#include "MediaOperationFactoryImpl.h"
+
+namespace AsteriskSCF
+{
+
+namespace MediaOperationsCore
+{
+
+class TranslatorOperationFactory : public MediaOperationFactoryImpl
+{
+public:
+
+    TranslatorOperationFactory(
+        const Ice::ObjectAdapterPtr& adapter,
+        const AsteriskSCF::System::Logging::Logger& logger,
+        const MediaOperationReplicationContextPtr& replicationContext,
+        const std::string& name);
+
+    AsteriskSCF::Media::V1::MediaOperationPrx createMediaOperation(
+            const AsteriskSCF::Media::V1::StreamSourcePrx& source,
+            const AsteriskSCF::Media::V1::StreamSinkPrx& sink,
+            const Ice::Current&);
+
+    virtual AsteriskSCF::Media::V1::MediaOperationPrx createMediaOperation(
+            const AsteriskSCF::Media::V1::FormatPtr& sourceFormat,
+            const AsteriskSCF::Media::V1::FormatPtr& sinkFormat,
+            const std::string& operationId) = 0;
+
+    void addTranslation(
+            const AsteriskSCF::Media::V1::FormatPtr&,
+            const AsteriskSCF::Media::V1::FormatSeq&,
+            int cost);
+
+    static bool formatsEqual1(
+            const AsteriskSCF::Media::V1::FormatPtr& lhs,
+            const AsteriskSCF::Media::V1::FormatPtr& rhs);
+
+    static bool formatsEqual2(
+            const AsteriskSCF::Media::V1::FormatPtr& lhs,
+            const std::pair<std::string, AsteriskSCF::Media::V1::FormatSeq>& rhs);
+
+private:
+    typedef std::map<std::string, AsteriskSCF::Media::V1::FormatSeq> TranslationMap;
+
+    TranslationMap mTranslations;
+};
+
+typedef IceUtil::Handle<TranslatorOperationFactory> TranslatorOperationFactoryPtr;
+
+}
+}
diff --git a/src/resample.cpp b/src/resample.cpp
index 5c60df8..9be11ac 100644
--- a/src/resample.cpp
+++ b/src/resample.cpp
@@ -250,67 +250,12 @@ typedef IceUtil::Handle<ResampleOperation> ResampleOperationPtr;
 ResampleFactory::ResampleFactory(const Ice::ObjectAdapterPtr& adapter,
         const AsteriskSCF::System::Logging::Logger& logger,
         const MediaOperationReplicationContextPtr& replicationContext)
-    : MediaOperationFactoryImpl(adapter, logger, replicationContext, "ResampleFactory")
+    : TranslatorOperationFactory(adapter, logger, replicationContext, "ResampleFactory")
 {
+    buildTranslations();
+
     pj_memset(&mCachingPool, 0, sizeof(mCachingPool));
     pj_caching_pool_init(&mCachingPool, NULL, 1024 * 1024);
-    buildSupportedFormats();
-    populateLocatorParams();
-}
-
-MediaOperationPrx ResampleFactory::createMediaOperation(
-        const StreamSourcePrx& source,
-        const StreamSinkPrx& sink,
-        const Ice::Current&)
-{
-    //Since we're expected to do a translation, we'd better
-    //be given both a source and a sink.
-    if (sink == 0 || source == 0)
-    {
-        mLogger(Error) << "Cannot create resampler because of a missing source or sink";
-        throw UnsupportedMediaFormatException();
-    }
-
-    FormatSeq sourceFormats = source->getFormats();
-    FormatSeq sinkFormats = sink->getFormats();
-
-    FormatSeq::iterator supportedInput =
-        std::find_first_of(sourceFormats.begin(),
-                sourceFormats.end(),
-                mSupportedInputFormats.begin(),
-                mSupportedInputFormats.end(),
-                formatCompare);
-
-    FormatSeq::iterator supportedOutput =
-        std::find_first_of(sinkFormats.begin(),
-                sinkFormats.end(),
-                mSupportedOutputFormats.begin(),
-                mSupportedOutputFormats.end(),
-                formatCompare);
-
-    if (supportedInput == sourceFormats.end()
-            || supportedOutput == sinkFormats.end())
-    {
-        mLogger(Error) << "Cannot create resampler because of unsupported formats";
-        throw UnsupportedMediaFormatException();
-    }
-
-    FormatPtr inputFormat = AudioFormatPtr::dynamicCast(*supportedInput);
-    FormatPtr outputFormat = AudioFormatPtr::dynamicCast(*supportedOutput);
-
-    //We've extracted the formats we give a @#$* about from
-    //the source and sink. Now, we have to determine which
-    //formats to actually use for creating the resampler. For
-    //now, we go with the lazy approach of taking whatever
-    //supported input and whatever supported output we found
-    //and using that.
-    mLogger(Debug) << "Creating a resampler from " << (*supportedInput)->name
-        << " to " << (*supportedOutput)->name;
-
-    return createMediaOperation(
-            *supportedOutput,
-            *supportedInput,
-            IceUtil::generateUUID());
 }
 
 MediaOperationPrx ResampleFactory::createMediaOperation(
@@ -331,49 +276,23 @@ MediaOperationPrx ResampleFactory::createMediaOperation(
     MediaOperationPrx proxy = operation->activate(operationId);
     return proxy;
 }
-void ResampleFactory::buildSupportedFormats()
+
+void ResampleFactory::buildTranslations()
 {
     FormatPtr slin8 = new SignedLinear();
     slin8->name = SignedLinear8Name;
 
-    mSupportedInputFormats.push_back(slin8);
-    mSupportedOutputFormats.push_back(slin8);
-
     FormatPtr slin16 = new SignedLinear();
     slin16->name = SignedLinear16Name;
 
-    mSupportedInputFormats.push_back(slin16);
-    mSupportedOutputFormats.push_back(slin16);
-}
-
-void ResampleFactory::populateLocatorParams()
-{
-    mLocatorParams->category = MediaOperationDiscoveryCategory;
-    mLocatorParams->service = MediaOperationDiscoveryTranslatorService;
-
-    for (FormatSeq::iterator inIter = mSupportedInputFormats.begin();
-            inIter != mSupportedInputFormats.end(); ++inIter)
-    {
-        for (FormatSeq::iterator outIter = mSupportedOutputFormats.begin();
-                outIter != mSupportedOutputFormats.end(); ++outIter)
-        {
-            //Don't create a resampler between the same format!
-            if (formatCompare(*inIter, *outIter))
-            {
-                continue;
-            }
-
-            mLogger(Debug) << "Creating resampler attributes from " << (*inIter)->name
-                << " to " << (*outIter)->name;
+    FormatSeq slin8Seq;
+    slin8Seq.push_back(slin8);
 
-            MediaOperationAttributes attrs;
-            attrs.inputFormat = *inIter;
-            attrs.outputFormat = *outIter;
-            attrs.cost = 100; //XXX COST?
+    FormatSeq slin16Seq;
+    slin16Seq.push_back(slin16);
 
-            mLocatorParams->attributes.push_back(attrs);
-        }
-    }
+    addTranslation(slin8, slin16Seq, 100);
+    addTranslation(slin16, slin8Seq, 100);
 }
 
 }
diff --git a/src/resample.h b/src/resample.h
index c0a5549..b3ae897 100644
--- a/src/resample.h
+++ b/src/resample.h
@@ -18,7 +18,7 @@
 
 #include <pjmedia.h>
 
-#include "MediaOperationFactoryImpl.h"
+#include "TranslatorOperationFactory.h"
 
 namespace AsteriskSCF
 {
@@ -26,32 +26,19 @@ namespace AsteriskSCF
 namespace MediaOperationsCore
 {
 
-class ResampleFactory : public MediaOperationFactoryImpl
+class ResampleFactory : public TranslatorOperationFactory
 {
 public:
     ResampleFactory(const Ice::ObjectAdapterPtr&,
             const AsteriskSCF::System::Logging::Logger& logger,
             const MediaOperationReplicationContextPtr& replicationContext);
 
-    void replicateState(const AsteriskSCF::Media::V1::MediaOperationPrx& proxy,
-            const AsteriskSCF::Media::V1::FormatPtr& sourceFormat,
-            const AsteriskSCF::Media::V1::FormatPtr& sinkFormat);
-
-    AsteriskSCF::Media::V1::MediaOperationPrx createMediaOperation(
-            const AsteriskSCF::Media::V1::StreamSourcePrx& source,
-            const AsteriskSCF::Media::V1::StreamSinkPrx& sink,
-            const Ice::Current&);
-
     AsteriskSCF::Media::V1::MediaOperationPrx createMediaOperation(
             const AsteriskSCF::Media::V1::FormatPtr& sourceFormat,
             const AsteriskSCF::Media::V1::FormatPtr& sinkFormat,
             const std::string& operationId);
 private:
-    void buildSupportedFormats();
-    void populateLocatorParams();
-
-    AsteriskSCF::Media::V1::FormatSeq mSupportedInputFormats;
-    AsteriskSCF::Media::V1::FormatSeq mSupportedOutputFormats;
+    void buildTranslations();
 
     pj_caching_pool mCachingPool;
 };
diff --git a/src/ulaw_alaw.cpp b/src/ulaw_alaw.cpp
index d5a140d..b7f944e 100644
--- a/src/ulaw_alaw.cpp
+++ b/src/ulaw_alaw.cpp
@@ -227,109 +227,27 @@ typedef IceUtil::Handle<UlawAlawOperation> UlawAlawOperationPtr;
 UlawAlawFactory::UlawAlawFactory(const Ice::ObjectAdapterPtr& adapter,
         const Logger& logger,
         const MediaOperationReplicationContextPtr& replicationContext)
-    : MediaOperationFactoryImpl(adapter, logger, replicationContext, "UlawAlawFactory")
+    : TranslatorOperationFactory(adapter, logger, replicationContext, "UlawAlawFactory")
 {
-    MediaOperationAttributes ulawToAlaw;
-    ulawToAlaw.inputFormat = new G711uLAW();
-    ulawToAlaw.inputFormat->name = G711uLAWName;
-    ulawToAlaw.outputFormat = new G711aLAW();
-    ulawToAlaw.outputFormat->name = G711aLAWName;
-    ulawToAlaw.cost = 100; //XXX COST?
-
-    MediaOperationAttributes alawToUlaw;
-    alawToUlaw.inputFormat = new G711aLAW();
-    alawToUlaw.inputFormat->name = G711aLAWName;
-    alawToUlaw.outputFormat = new G711uLAW();
-    alawToUlaw.outputFormat->name = G711uLAWName;
-    alawToUlaw.cost = 100; //XXX COST?
-
-    mLocatorParams->category = MediaOperationDiscoveryCategory;
-    mLocatorParams->service = MediaOperationDiscoveryTranslatorService;
-    mLocatorParams->attributes.push_back(ulawToAlaw);
-    mLocatorParams->attributes.push_back(alawToUlaw);
+    buildTranslations();
 }
 
-MediaOperationPrx UlawAlawFactory::createMediaOperation(
-        const StreamSourcePrx& source,
-        const StreamSinkPrx& sink,
-        const Ice::Current&)
+void UlawAlawFactory::buildTranslations()
 {
-    //Since we're expected to do a translation, we'd better
-    //be given both a source and a sink.
... 132 lines suppressed ...


-- 
asterisk-scf/integration/media_operations_core.git



More information about the asterisk-scf-commits mailing list