Add options for NetEq fast accelerate mode through libjingle

This CL connects RTCConfiguration::audioJitterBufferFastMode in
PeerConnection.java, through libjingle, down to
NetEq::Config::enable_fast_accelerate in native WebRTC.

When enabled, it will allow NetEq to do faster time-compression when
the buffer level is very high.

BUG=4691
R=henrika@webrtc.org, mflodman@webrtc.org, pthatcher@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#9344}
diff --git a/talk/app/webrtc/java/jni/peerconnection_jni.cc b/talk/app/webrtc/java/jni/peerconnection_jni.cc
index f96b026..69078e6 100644
--- a/talk/app/webrtc/java/jni/peerconnection_jni.cc
+++ b/talk/app/webrtc/java/jni/peerconnection_jni.cc
@@ -1330,6 +1330,8 @@
   jfieldID j_audio_jitter_buffer_max_packets_id = GetFieldID(
       jni, j_rtc_config_class, "audioJitterBufferMaxPackets",
       "I");
+  jfieldID j_audio_jitter_buffer_fast_accelerate_id = GetFieldID(
+      jni, j_rtc_config_class, "audioJitterBufferFastAccelerate", "Z");
   PeerConnectionInterface::RTCConfiguration rtc_config;
 
   rtc_config.type =
@@ -1342,6 +1344,8 @@
   JavaIceServersToJsepIceServers(jni, j_ice_servers, &rtc_config.servers);
   rtc_config.audio_jitter_buffer_max_packets =
       GetIntField(jni, j_rtc_config, j_audio_jitter_buffer_max_packets_id);
+  rtc_config.audio_jitter_buffer_fast_accelerate = GetBooleanField(
+      jni, j_rtc_config, j_audio_jitter_buffer_fast_accelerate_id);
 
   PCOJava* observer = reinterpret_cast<PCOJava*>(observer_p);
   observer->SetConstraints(new ConstraintsWrapper(jni, j_constraints));
diff --git a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java
index a229e17..8da2c45 100644
--- a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java
+++ b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java
@@ -134,6 +134,7 @@
     public RtcpMuxPolicy rtcpMuxPolicy;
     public TcpCandidatePolicy tcpCandidatePolicy;
     public int audioJitterBufferMaxPackets;
+    public boolean audioJitterBufferFastAccelerate;
 
     public RTCConfiguration(List<IceServer> iceServers) {
       iceTransportsType = IceTransportsType.ALL;
@@ -142,6 +143,7 @@
       tcpCandidatePolicy = TcpCandidatePolicy.ENABLED;
       this.iceServers = iceServers;
       audioJitterBufferMaxPackets = 50;
+      audioJitterBufferFastAccelerate = false;
     }
   };
 
diff --git a/talk/app/webrtc/peerconnectioninterface.h b/talk/app/webrtc/peerconnectioninterface.h
index 59cc700..3e4cb55 100644
--- a/talk/app/webrtc/peerconnectioninterface.h
+++ b/talk/app/webrtc/peerconnectioninterface.h
@@ -222,13 +222,15 @@
     RtcpMuxPolicy rtcp_mux_policy;
     TcpCandidatePolicy tcp_candidate_policy;
     int audio_jitter_buffer_max_packets;
+    bool audio_jitter_buffer_fast_accelerate;
 
     RTCConfiguration()
         : type(kAll),
           bundle_policy(kBundlePolicyBalanced),
           rtcp_mux_policy(kRtcpMuxPolicyNegotiate),
           tcp_candidate_policy(kTcpCandidatePolicyEnabled),
-          audio_jitter_buffer_max_packets(50) {}
+          audio_jitter_buffer_max_packets(50),
+          audio_jitter_buffer_fast_accelerate(false) {}
   };
 
   struct RTCOfferAnswerOptions {
diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc
index 766c5d4..5c8b2df 100644
--- a/talk/app/webrtc/webrtcsession.cc
+++ b/talk/app/webrtc/webrtcsession.cc
@@ -644,6 +644,9 @@
   audio_options_.audio_jitter_buffer_max_packets.Set(
       rtc_configuration.audio_jitter_buffer_max_packets);
 
+  audio_options_.audio_jitter_buffer_fast_accelerate.Set(
+      rtc_configuration.audio_jitter_buffer_fast_accelerate);
+
   const cricket::VideoCodec default_codec(
       JsepSessionDescription::kDefaultVideoCodecId,
       JsepSessionDescription::kDefaultVideoCodecName,
diff --git a/talk/media/base/mediachannel.h b/talk/media/base/mediachannel.h
index 68e01ce..d96fe1c 100644
--- a/talk/media/base/mediachannel.h
+++ b/talk/media/base/mediachannel.h
@@ -152,6 +152,8 @@
     stereo_swapping.SetFrom(change.stereo_swapping);
     audio_jitter_buffer_max_packets.SetFrom(
         change.audio_jitter_buffer_max_packets);
+    audio_jitter_buffer_fast_accelerate.SetFrom(
+        change.audio_jitter_buffer_fast_accelerate);
     typing_detection.SetFrom(change.typing_detection);
     aecm_generate_comfort_noise.SetFrom(change.aecm_generate_comfort_noise);
     conference_mode.SetFrom(change.conference_mode);
@@ -183,6 +185,8 @@
         highpass_filter == o.highpass_filter &&
         stereo_swapping == o.stereo_swapping &&
         audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
+        audio_jitter_buffer_fast_accelerate ==
+            o.audio_jitter_buffer_fast_accelerate &&
         typing_detection == o.typing_detection &&
         aecm_generate_comfort_noise == o.aecm_generate_comfort_noise &&
         conference_mode == o.conference_mode &&
@@ -215,6 +219,8 @@
     ost << ToStringIfSet("swap", stereo_swapping);
     ost << ToStringIfSet("audio_jitter_buffer_max_packets",
                          audio_jitter_buffer_max_packets);
+    ost << ToStringIfSet("audio_jitter_buffer_fast_accelerate",
+                         audio_jitter_buffer_fast_accelerate);
     ost << ToStringIfSet("typing", typing_detection);
     ost << ToStringIfSet("comfort_noise", aecm_generate_comfort_noise);
     ost << ToStringIfSet("conference", conference_mode);
@@ -255,6 +261,8 @@
   Settable<bool> stereo_swapping;
   // Audio receiver jitter buffer (NetEq) max capacity in number of packets.
   Settable<int> audio_jitter_buffer_max_packets;
+  // Audio receiver jitter buffer (NetEq) fast accelerate mode.
+  Settable<bool> audio_jitter_buffer_fast_accelerate;
   // Audio processing to detect typing.
   Settable<bool> typing_detection;
   Settable<bool> aecm_generate_comfort_noise;
diff --git a/talk/media/webrtc/fakewebrtcvoiceengine.h b/talk/media/webrtc/fakewebrtcvoiceengine.h
index 673e3e0..971f9f0 100644
--- a/talk/media/webrtc/fakewebrtcvoiceengine.h
+++ b/talk/media/webrtc/fakewebrtcvoiceengine.h
@@ -216,7 +216,8 @@
           send_absolute_sender_time_ext_(-1),
           receive_absolute_sender_time_ext_(-1),
           associate_send_channel(-1),
-          neteq_capacity(-1) {
+          neteq_capacity(-1),
+          neteq_fast_accelerate(false) {
       memset(&send_codec, 0, sizeof(send_codec));
       memset(&rx_agc_config, 0, sizeof(rx_agc_config));
     }
@@ -254,6 +255,7 @@
     webrtc::PacketTime last_rtp_packet_time;
     std::list<std::string> packets;
     int neteq_capacity;
+    bool neteq_fast_accelerate;
   };
 
   FakeWebRtcVoiceEngine(const cricket::AudioCodec* const* codecs,
@@ -409,6 +411,8 @@
     if (config.Get<webrtc::NetEqCapacityConfig>().enabled) {
       ch->neteq_capacity = config.Get<webrtc::NetEqCapacityConfig>().capacity;
     }
+    ch->neteq_fast_accelerate =
+        config.Get<webrtc::NetEqFastAccelerate>().enabled;
     channels_[++last_channel_] = ch;
     return last_channel_;
   }
@@ -1193,6 +1197,11 @@
     ASSERT(ch != channels_.end());
     return ch->second->neteq_capacity;
   }
+  bool GetNetEqFastAccelerate() const {
+    auto ch = channels_.find(last_channel_);
+    ASSERT(ch != channels_.end());
+    return ch->second->neteq_fast_accelerate;
+  }
 
  private:
   int GetNumDevices(int& num) {
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
index 230953e..7f000ab 100644
--- a/talk/media/webrtc/webrtcvoiceengine.cc
+++ b/talk/media/webrtc/webrtcvoiceengine.cc
@@ -352,6 +352,7 @@
   options.highpass_filter.Set(true);
   options.stereo_swapping.Set(false);
   options.audio_jitter_buffer_max_packets.Set(50);
+  options.audio_jitter_buffer_fast_accelerate.Set(false);
   options.typing_detection.Set(true);
   options.conference_mode.Set(false);
   options.adjust_agc_delta.Set(0);
@@ -801,6 +802,14 @@
         new webrtc::NetEqCapacityConfig(audio_jitter_buffer_max_packets));
   }
 
+  bool audio_jitter_buffer_fast_accelerate;
+  if (options.audio_jitter_buffer_fast_accelerate.Get(
+          &audio_jitter_buffer_fast_accelerate)) {
+    LOG(LS_INFO) << "NetEq fast mode? " << audio_jitter_buffer_fast_accelerate;
+    voe_config_.Set<webrtc::NetEqFastAccelerate>(
+        new webrtc::NetEqFastAccelerate(audio_jitter_buffer_fast_accelerate));
+  }
+
   bool typing_detection;
   if (options.typing_detection.Get(&typing_detection)) {
     LOG(LS_INFO) << "Typing detection is enabled? " << typing_detection;
diff --git a/talk/media/webrtc/webrtcvoiceengine_unittest.cc b/talk/media/webrtc/webrtcvoiceengine_unittest.cc
index 6580011..0f2c73a 100644
--- a/talk/media/webrtc/webrtcvoiceengine_unittest.cc
+++ b/talk/media/webrtc/webrtcvoiceengine_unittest.cc
@@ -2843,6 +2843,8 @@
   EXPECT_EQ(ec_mode, webrtc::kEcConference);
   EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
   EXPECT_EQ(50, voe_.GetNetEqCapacity());  // From GetDefaultEngineOptions().
+  EXPECT_FALSE(
+      voe_.GetNetEqFastAccelerate());  // From GetDefaultEngineOptions().
 
   // Turn echo cancellation off
   options.echo_cancellation.Set(false);
diff --git a/webrtc/config.h b/webrtc/config.h
index 09633ed..804f54d 100644
--- a/webrtc/config.h
+++ b/webrtc/config.h
@@ -127,6 +127,12 @@
   int capacity;
 };
 
+struct NetEqFastAccelerate {
+  NetEqFastAccelerate() : enabled(false) {}
+  explicit NetEqFastAccelerate(bool value) : enabled(value) {}
+  bool enabled;
+};
+
 }  // namespace webrtc
 
 #endif  // WEBRTC_CONFIG_H_
diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc
index af2c58e..063ffa6 100644
--- a/webrtc/voice_engine/channel.cc
+++ b/webrtc/voice_engine/channel.cc
@@ -817,6 +817,8 @@
       acm_config.neteq_config.max_packets_in_buffer =
           std::max(20, config.Get<NetEqCapacityConfig>().capacity);
     }
+    acm_config.neteq_config.enable_fast_accelerate =
+        config.Get<NetEqFastAccelerate>().enabled;
     audio_coding_.reset(AudioCodingModule::Create(acm_config));
 
     _inbandDtmfQueue.ResetDtmf();