This issue is related to
https://chromereviews.googleplex.com/9908014/

I was thinking about shipping ACM2 from the signal repository. There seems to be too many changes in one CL.

BUG=
R=andrew@webrtc.org, turaj@webrtc.org, xians@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/2171004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4733 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_coding/main/interface/audio_coding_module.h b/webrtc/modules/audio_coding/main/interface/audio_coding_module.h
index b705b4d..12b5a63 100644
--- a/webrtc/modules/audio_coding/main/interface/audio_coding_module.h
+++ b/webrtc/modules/audio_coding/main/interface/audio_coding_module.h
@@ -1017,6 +1017,20 @@
   virtual std::vector<uint16_t> GetNackList(int round_trip_time_ms) const = 0;
 };
 
+struct AudioCodingModuleFactory {
+  AudioCodingModuleFactory() {}
+  virtual ~AudioCodingModuleFactory() {}
+
+  virtual AudioCodingModule* Create(int id) const;
+};
+
+struct NewAudioCodingModuleFactory : AudioCodingModuleFactory {
+  NewAudioCodingModuleFactory() {}
+  virtual ~NewAudioCodingModuleFactory() {}
+
+  virtual AudioCodingModule* Create(int id) const;
+};
+
 }  // namespace webrtc
 
 #endif  // WEBRTC_MODULES_AUDIO_CODING_MAIN_INTERFACE_AUDIO_CODING_MODULE_H_
diff --git a/webrtc/modules/audio_coding/main/source/audio_coding_module.cc b/webrtc/modules/audio_coding/main/source/audio_coding_module.cc
index 570fec5..4ac40b7 100644
--- a/webrtc/modules/audio_coding/main/source/audio_coding_module.cc
+++ b/webrtc/modules/audio_coding/main/source/audio_coding_module.cc
@@ -98,4 +98,14 @@
   }
 }
 
+AudioCodingModule* AudioCodingModuleFactory::Create(int id) const {
+  return new AudioCodingModuleImpl(static_cast<int32_t>(id),
+                                   Clock::GetRealTimeClock());
+}
+
+AudioCodingModule* NewAudioCodingModuleFactory::Create(int id) const {
+  // TODO(minyue): return new AudioCodingModuleImpl (new version).
+  return NULL;
+}
+
 }  // namespace webrtc
diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc
index 9655471..b1a2aa6 100644
--- a/webrtc/voice_engine/channel.cc
+++ b/webrtc/voice_engine/channel.cc
@@ -10,6 +10,7 @@
 
 #include "webrtc/voice_engine/channel.h"
 
+#include "webrtc/common.h"
 #include "webrtc/modules/audio_device/include/audio_device.h"
 #include "webrtc/modules/audio_processing/include/audio_processing.h"
 #include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
@@ -816,13 +817,14 @@
 int32_t
 Channel::CreateChannel(Channel*& channel,
                        int32_t channelId,
-                       uint32_t instanceId)
+                       uint32_t instanceId,
+                       const Config& config)
 {
     WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId,channelId),
                  "Channel::CreateChannel(channelId=%d, instanceId=%d)",
         channelId, instanceId);
 
-    channel = new Channel(channelId, instanceId);
+    channel = new Channel(channelId, instanceId, config);
     if (channel == NULL)
     {
         WEBRTC_TRACE(kTraceMemory, kTraceVoice,
@@ -900,7 +902,8 @@
 }
 
 Channel::Channel(int32_t channelId,
-                 uint32_t instanceId) :
+                 uint32_t instanceId,
+                 const Config& config) :
     _fileCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
     _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
     _instanceId(instanceId),
@@ -915,7 +918,7 @@
         VoEModuleId(instanceId, channelId), Clock::GetRealTimeClock(), this,
         this, this, rtp_payload_registry_.get())),
     telephone_event_handler_(rtp_receiver_->GetTelephoneEventHandler()),
-    _audioCodingModule(*AudioCodingModule::Create(
+    _audioCodingModule(*config.Get<AudioCodingModuleFactory>().Create(
         VoEModuleId(instanceId, channelId))),
     _rtpDumpIn(*RtpDump::CreateRtpDump()),
     _rtpDumpOut(*RtpDump::CreateRtpDump()),
diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h
index a614707..4d9146e 100644
--- a/webrtc/voice_engine/channel.h
+++ b/webrtc/voice_engine/channel.h
@@ -36,6 +36,7 @@
 namespace webrtc
 {
 class AudioDeviceModule;
+class Config;
 class CriticalSectionWrapper;
 class FileWrapper;
 class ProcessThread;
@@ -80,8 +81,9 @@
     virtual ~Channel();
     static int32_t CreateChannel(Channel*& channel,
                                  int32_t channelId,
-                                 uint32_t instanceId);
-    Channel(int32_t channelId, uint32_t instanceId);
+                                 uint32_t instanceId,
+                                 const Config& config);
+    Channel(int32_t channelId, uint32_t instanceId, const Config& config);
     int32_t Init();
     int32_t SetEngineInformation(
         Statistics& engineStatistics,
diff --git a/webrtc/voice_engine/channel_manager.cc b/webrtc/voice_engine/channel_manager.cc
index 8110bb6..b56c54a 100644
--- a/webrtc/voice_engine/channel_manager.cc
+++ b/webrtc/voice_engine/channel_manager.cc
@@ -44,14 +44,15 @@
 ChannelOwner::ChannelRef::ChannelRef(class Channel* channel)
     : channel(channel), ref_count(1) {}
 
-ChannelManager::ChannelManager(uint32_t instance_id)
+ChannelManager::ChannelManager(uint32_t instance_id, const Config& config)
     : instance_id_(instance_id),
       last_channel_id_(-1),
-      lock_(CriticalSectionWrapper::CreateCriticalSection()) {}
+      lock_(CriticalSectionWrapper::CreateCriticalSection()),
+      config_(config) {}
 
 ChannelOwner ChannelManager::CreateChannel() {
   Channel* channel;
-  Channel::CreateChannel(channel, ++last_channel_id_, instance_id_);
+  Channel::CreateChannel(channel, ++last_channel_id_, instance_id_, config_);
   ChannelOwner channel_owner(channel);
 
   CriticalSectionScoped crit(lock_.get());
diff --git a/webrtc/voice_engine/channel_manager.h b/webrtc/voice_engine/channel_manager.h
index 4efeb15..85e64fa 100644
--- a/webrtc/voice_engine/channel_manager.h
+++ b/webrtc/voice_engine/channel_manager.h
@@ -20,6 +20,9 @@
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
+
+class Config;
+
 namespace voe {
 
 class Channel;
@@ -66,7 +69,7 @@
 
 class ChannelManager {
  public:
-  ChannelManager(uint32_t instance_id);
+  ChannelManager(uint32_t instance_id, const Config& config);
 
   // Upon construction of an Iterator it will grab a copy of the channel list of
   // the ChannelManager. The iteration will then occur over this state, not the
@@ -110,6 +113,8 @@
   scoped_ptr<CriticalSectionWrapper> lock_;
   std::vector<ChannelOwner> channels_;
 
+  const Config& config_;
+
   DISALLOW_COPY_AND_ASSIGN(ChannelManager);
 };
 }  // namespace voe
diff --git a/webrtc/voice_engine/include/voe_base.h b/webrtc/voice_engine/include/voe_base.h
index de483b4..6859ddb 100644
--- a/webrtc/voice_engine/include/voe_base.h
+++ b/webrtc/voice_engine/include/voe_base.h
@@ -40,6 +40,7 @@
 
 class AudioDeviceModule;
 class AudioProcessing;
+class Config;
 
 const int kVoEDefault = -1;
 
@@ -63,6 +64,7 @@
     // Creates a VoiceEngine object, which can then be used to acquire
     // sub-APIs. Returns NULL on failure.
     static VoiceEngine* Create();
+    static VoiceEngine* Create(const Config& config);
 
     // Deletes a created VoiceEngine object and releases the utilized resources.
     // Note that if there are outstanding references held via other interfaces,
diff --git a/webrtc/voice_engine/shared_data.cc b/webrtc/voice_engine/shared_data.cc
index 843d5db..2d485ae 100644
--- a/webrtc/voice_engine/shared_data.cc
+++ b/webrtc/voice_engine/shared_data.cc
@@ -23,10 +23,10 @@
 
 static int32_t _gInstanceCounter = 0;
 
-SharedData::SharedData() :
+SharedData::SharedData(const Config& config) :
     _instanceId(++_gInstanceCounter),
     _apiCritPtr(CriticalSectionWrapper::CreateCriticalSection()),
-    _channelManager(_gInstanceCounter),
+    _channelManager(_gInstanceCounter, config),
     _engineStatistics(_gInstanceCounter),
     _audioDevicePtr(NULL),
     audioproc_(NULL),
diff --git a/webrtc/voice_engine/shared_data.h b/webrtc/voice_engine/shared_data.h
index a841547..7c7ad5c 100644
--- a/webrtc/voice_engine/shared_data.h
+++ b/webrtc/voice_engine/shared_data.h
@@ -22,6 +22,7 @@
 class ProcessThread;
 
 namespace webrtc {
+class Config;
 class CriticalSectionWrapper;
 
 namespace voe {
@@ -79,7 +80,7 @@
 
     AudioDeviceModule::AudioLayer _audioDeviceLayer;
 
-    SharedData();
+    SharedData(const Config& config);
     virtual ~SharedData();
 };
 
diff --git a/webrtc/voice_engine/voice_engine_impl.cc b/webrtc/voice_engine/voice_engine_impl.cc
index 4c923eb..703b6a4 100644
--- a/webrtc/voice_engine/voice_engine_impl.cc
+++ b/webrtc/voice_engine/voice_engine_impl.cc
@@ -16,6 +16,7 @@
 #endif
 #endif
 
+#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 #include "webrtc/voice_engine/voice_engine_impl.h"
 
@@ -28,13 +29,26 @@
 // improvement here.
 static int32_t gVoiceEngineInstanceCounter = 0;
 
-extern "C"
+VoiceEngine* GetVoiceEngine(const Config* config, bool owns_config)
 {
-WEBRTC_DLLEXPORT VoiceEngine* GetVoiceEngine();
+#if (defined _WIN32)
+  HMODULE hmod = LoadLibrary(TEXT("VoiceEngineTestingDynamic.dll"));
 
-VoiceEngine* GetVoiceEngine()
-{
-    VoiceEngineImpl* self = new VoiceEngineImpl();
+  if (hmod) {
+    typedef VoiceEngine* (*PfnGetVoiceEngine)(void);
+    PfnGetVoiceEngine pfn = (PfnGetVoiceEngine)GetProcAddress(
+        hmod,"GetVoiceEngine");
+    if (pfn) {
+      VoiceEngine* self = pfn();
+      if (owns_config) {
+        delete config;
+      }
+      return (self);
+    }
+  }
+#endif
+
+    VoiceEngineImpl* self = new VoiceEngineImpl(config, owns_config);
     if (self != NULL)
     {
         self->AddRef();  // First reference.  Released in VoiceEngine::Delete.
@@ -42,7 +56,6 @@
     }
     return self;
 }
-}  // extern "C"
 
 int VoiceEngineImpl::AddRef() {
   return ++_ref_count;
@@ -63,25 +76,15 @@
   return new_ref;
 }
 
-VoiceEngine* VoiceEngine::Create()
-{
-#if (defined _WIN32)
-    HMODULE hmod_ = LoadLibrary(TEXT("VoiceEngineTestingDynamic.dll"));
+VoiceEngine* VoiceEngine::Create() {
+  Config* config = new Config();
+  config->Set<AudioCodingModuleFactory>(new AudioCodingModuleFactory());
 
-    if (hmod_)
-    {
-        typedef VoiceEngine* (*PfnGetVoiceEngine)(void);
-        PfnGetVoiceEngine pfn = (PfnGetVoiceEngine)GetProcAddress(
-                hmod_,"GetVoiceEngine");
-        if (pfn)
-        {
-            VoiceEngine* self = pfn();
-            return (self);
-        }
-    }
-#endif
+  return GetVoiceEngine(config, true);
+}
 
-    return GetVoiceEngine();
+VoiceEngine* VoiceEngine::Create(const Config& config) {
+  return GetVoiceEngine(&config, false);
 }
 
 int VoiceEngine::SetTraceFilter(unsigned int filter)
diff --git a/webrtc/voice_engine/voice_engine_impl.h b/webrtc/voice_engine/voice_engine_impl.h
index 55c4209..fe6a791 100644
--- a/webrtc/voice_engine/voice_engine_impl.h
+++ b/webrtc/voice_engine/voice_engine_impl.h
@@ -98,7 +98,8 @@
                         public VoEBaseImpl
 {
 public:
-    VoiceEngineImpl() : 
+    VoiceEngineImpl(const Config* config, bool owns_config) :
+        SharedData(*config),
 #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
         VoEAudioProcessingImpl(this),
 #endif
@@ -137,7 +138,8 @@
         VoEVolumeControlImpl(this),
 #endif
         VoEBaseImpl(this),
-        _ref_count(0)
+        _ref_count(0),
+        own_config_(owns_config ? config : NULL)
     {
     }
     virtual ~VoiceEngineImpl()
@@ -152,6 +154,7 @@
 
 private:
     Atomic32 _ref_count;
+    scoped_ptr<const Config> own_config_;
 };
 
 }  // namespace webrtc