Injectable audio encoders: voice_engine/channel changes.

Adds a SetEncoder call to voe::Channel, so that we can move encoder setup outside of Voice Engine.

BUG=webrtc:5806

Review-Url: https://codereview.webrtc.org/2703373006
Cr-Original-Commit-Position: refs/heads/master@{#17572}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 1ffbd6c93cf322de23b3772c39021c58abe4b7bc
diff --git a/test/mock_voe_channel_proxy.h b/test/mock_voe_channel_proxy.h
index b62c266..a0ccd45 100644
--- a/test/mock_voe_channel_proxy.h
+++ b/test/mock_voe_channel_proxy.h
@@ -22,6 +22,14 @@
 
 class MockVoEChannelProxy : public voe::ChannelProxy {
  public:
+  // GTest doesn't like move-only types, like std::unique_ptr
+  bool SetEncoder(int payload_type,
+                  std::unique_ptr<AudioEncoder> encoder) {
+    return SetEncoderForMock(payload_type, &encoder);
+  }
+  MOCK_METHOD2(SetEncoderForMock,
+               bool(int payload_type,
+                    std::unique_ptr<AudioEncoder>* encoder));
   MOCK_METHOD1(SetRTCPStatus, void(bool enable));
   MOCK_METHOD1(SetLocalSSRC, void(uint32_t ssrc));
   MOCK_METHOD1(SetRTCP_CNAME, void(const std::string& c_name));
diff --git a/voice_engine/BUILD.gn b/voice_engine/BUILD.gn
index ba79b2d..7a4641f 100644
--- a/voice_engine/BUILD.gn
+++ b/voice_engine/BUILD.gn
@@ -146,6 +146,7 @@
     "../call:call_interfaces",
     "../common_audio",
     "../logging:rtc_event_log_api",
+    "../modules/audio_coding:audio_encoder_interface",
     "../modules/audio_coding:audio_format_conversion",
     "../modules/audio_coding:rent_a_codec",
     "../modules/audio_conference_mixer",
diff --git a/voice_engine/channel.cc b/voice_engine/channel.cc
index 3a4a970..a7a45e6 100644
--- a/voice_engine/channel.cc
+++ b/voice_engine/channel.cc
@@ -1274,6 +1274,38 @@
   _rtpRtcpModule->SetSendingMediaStatus(false);
 }
 
+bool Channel::SetEncoder(int payload_type,
+                         std::unique_ptr<AudioEncoder> encoder) {
+  RTC_DCHECK_GE(payload_type, 0);
+  RTC_DCHECK_LE(payload_type, 127);
+  // TODO(ossu): Make a CodecInst up for now. It seems like very little of this
+  // information is actually used, possibly only payload type and clock rate.
+  CodecInst lies;
+  lies.pltype = payload_type;
+  strncpy(lies.plname, "audio", sizeof(lies.plname));
+  lies.plname[sizeof(lies.plname) - 1] = 0;
+  // Seems unclear if it should be clock rate or sample rate. CodecInst
+  // supposedly carries the sample rate, but only clock rate seems sensible to
+  // send to the RTP/RTCP module.
+  lies.plfreq = encoder->RtpTimestampRateHz();
+  lies.pacsize = 0;
+  lies.channels = encoder->NumChannels();
+  lies.rate = 0;
+
+  if (_rtpRtcpModule->RegisterSendPayload(lies) != 0) {
+    _rtpRtcpModule->DeRegisterSendPayload(payload_type);
+    if (_rtpRtcpModule->RegisterSendPayload(lies) != 0) {
+      WEBRTC_TRACE(
+          kTraceError, kTraceVoice, VoEId(_instanceId, _channelId),
+          "SetEncoder() failed to register codec to RTP/RTCP module");
+      return false;
+    }
+  }
+
+  audio_coding_->SetEncoder(std::move(encoder));
+  return true;
+}
+
 int32_t Channel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) {
   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
                "Channel::RegisterVoiceEngineObserver()");
diff --git a/voice_engine/channel.h b/voice_engine/channel.h
index 13d8e49..b43c737 100644
--- a/voice_engine/channel.h
+++ b/voice_engine/channel.h
@@ -23,6 +23,7 @@
 #include "webrtc/common_types.h"
 #include "webrtc/modules/audio_coding/acm2/codec_manager.h"
 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
 #include "webrtc/modules/audio_coding/include/audio_coding_module.h"
 #include "webrtc/modules/audio_conference_mixer/include/audio_conference_mixer_defines.h"
 #include "webrtc/modules/audio_processing/rms_level.h"
@@ -172,6 +173,9 @@
 
   void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs);
 
+  // Send using this encoder, with this payload type.
+  bool SetEncoder(int payload_type, std::unique_ptr<AudioEncoder> encoder);
+
   // API methods
 
   // VoEBase
diff --git a/voice_engine/channel_proxy.cc b/voice_engine/channel_proxy.cc
index bb56b07..ac96fe9 100644
--- a/voice_engine/channel_proxy.cc
+++ b/voice_engine/channel_proxy.cc
@@ -30,6 +30,12 @@
 
 ChannelProxy::~ChannelProxy() {}
 
+bool ChannelProxy::SetEncoder(int payload_type,
+                              std::unique_ptr<AudioEncoder> encoder) {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+  return channel()->SetEncoder(payload_type, std::move(encoder));
+}
+
 void ChannelProxy::SetRTCPStatus(bool enable) {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   channel()->SetRTCPStatus(enable);
diff --git a/voice_engine/channel_proxy.h b/voice_engine/channel_proxy.h
index 86b5e65..d964bd4 100644
--- a/voice_engine/channel_proxy.h
+++ b/voice_engine/channel_proxy.h
@@ -15,6 +15,7 @@
 #include "webrtc/base/constructormagic.h"
 #include "webrtc/base/race_checker.h"
 #include "webrtc/base/thread_checker.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
 #include "webrtc/voice_engine/channel_manager.h"
 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
 
@@ -54,6 +55,9 @@
   explicit ChannelProxy(const ChannelOwner& channel_owner);
   virtual ~ChannelProxy();
 
+  virtual bool SetEncoder(int payload_type,
+                          std::unique_ptr<AudioEncoder> encoder);
+
   virtual void SetRTCPStatus(bool enable);
   virtual void SetLocalSSRC(uint32_t ssrc);
   virtual void SetRTCP_CNAME(const std::string& c_name);