Turn webrtc::Vad into a pure virtual interface

Review URL: https://codereview.webrtc.org/1317243005

Cr-Commit-Position: refs/heads/master@{#9899}
diff --git a/webrtc/common_audio/vad/include/vad.h b/webrtc/common_audio/vad/include/vad.h
index 72c0949..087970f 100644
--- a/webrtc/common_audio/vad/include/vad.h
+++ b/webrtc/common_audio/vad/include/vad.h
@@ -12,12 +12,12 @@
 #define WEBRTC_COMMON_AUDIO_VAD_INCLUDE_VAD_H_
 
 #include "webrtc/base/checks.h"
+#include "webrtc/base/scoped_ptr.h"
 #include "webrtc/common_audio/vad/include/webrtc_vad.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
 
-// This is a C++ wrapper class for WebRtcVad.
 class Vad {
  public:
   enum Aggressiveness {
@@ -29,21 +29,22 @@
 
   enum Activity { kPassive = 0, kActive = 1, kError = -1 };
 
-  explicit Vad(enum Aggressiveness mode);
+  virtual ~Vad() = default;
 
-  virtual ~Vad();
-
+  // Calculates a VAD decision for the given audio frame. Valid sample rates
+  // are 8000, 16000, and 32000 Hz; the number of samples must be such that the
+  // frame is 10, 20, or 30 ms long.
   virtual Activity VoiceActivity(const int16_t* audio,
                                  size_t num_samples,
-                                 int sample_rate_hz);
+                                 int sample_rate_hz) = 0;
 
-  // Reset VAD state.
-  virtual void Reset();
-
- private:
-  VadInst* handle_;
-  Aggressiveness aggressiveness_;
+  // Resets VAD state.
+  virtual void Reset() = 0;
 };
 
+// Returns a Vad instance that's implemented on top of WebRtcVad.
+rtc::scoped_ptr<Vad> CreateVad(Vad::Aggressiveness aggressiveness);
+
 }  // namespace webrtc
+
 #endif  // WEBRTC_COMMON_AUDIO_VAD_INCLUDE_VAD_H_
diff --git a/webrtc/common_audio/vad/mock/mock_vad.h b/webrtc/common_audio/vad/mock/mock_vad.h
index 916480a..bc763bb 100644
--- a/webrtc/common_audio/vad/mock/mock_vad.h
+++ b/webrtc/common_audio/vad/mock/mock_vad.h
@@ -19,7 +19,6 @@
 
 class MockVad : public Vad {
  public:
-  explicit MockVad(enum Aggressiveness mode) : Vad(mode) {}
   virtual ~MockVad() { Die(); }
   MOCK_METHOD0(Die, void());
 
diff --git a/webrtc/common_audio/vad/vad.cc b/webrtc/common_audio/vad/vad.cc
index dc4eb6d..8973a68 100644
--- a/webrtc/common_audio/vad/vad.cc
+++ b/webrtc/common_audio/vad/vad.cc
@@ -14,36 +14,50 @@
 
 namespace webrtc {
 
-Vad::Vad(enum Aggressiveness mode) : handle_(nullptr), aggressiveness_(mode) {
-  Reset();
-}
+namespace {
 
-Vad::~Vad() {
-  WebRtcVad_Free(handle_);
-}
-
-enum Vad::Activity Vad::VoiceActivity(const int16_t* audio,
-                                      size_t num_samples,
-                                      int sample_rate_hz) {
-  int ret = WebRtcVad_Process(handle_, sample_rate_hz, audio, num_samples);
-  switch (ret) {
-    case 0:
-      return kPassive;
-    case 1:
-      return kActive;
-    default:
-      DCHECK(false) << "WebRtcVad_Process returned an error.";
-      return kError;
+class VadImpl final : public Vad {
+ public:
+  explicit VadImpl(Aggressiveness aggressiveness)
+      : handle_(nullptr), aggressiveness_(aggressiveness) {
+    Reset();
   }
-}
 
-void Vad::Reset() {
-  if (handle_)
-    WebRtcVad_Free(handle_);
-  handle_ = WebRtcVad_Create();
-  CHECK(handle_);
-  CHECK_EQ(WebRtcVad_Init(handle_), 0);
-  CHECK_EQ(WebRtcVad_set_mode(handle_, aggressiveness_), 0);
+  ~VadImpl() override { WebRtcVad_Free(handle_); }
+
+  Activity VoiceActivity(const int16_t* audio,
+                         size_t num_samples,
+                         int sample_rate_hz) override {
+    int ret = WebRtcVad_Process(handle_, sample_rate_hz, audio, num_samples);
+    switch (ret) {
+      case 0:
+        return kPassive;
+      case 1:
+        return kActive;
+      default:
+        DCHECK(false) << "WebRtcVad_Process returned an error.";
+        return kError;
+    }
+  }
+
+  void Reset() override {
+    if (handle_)
+      WebRtcVad_Free(handle_);
+    handle_ = WebRtcVad_Create();
+    CHECK(handle_);
+    CHECK_EQ(WebRtcVad_Init(handle_), 0);
+    CHECK_EQ(WebRtcVad_set_mode(handle_, aggressiveness_), 0);
+  }
+
+ private:
+  VadInst* handle_;
+  Aggressiveness aggressiveness_;
+};
+
+}  // namespace
+
+rtc::scoped_ptr<Vad> CreateVad(Vad::Aggressiveness aggressiveness) {
+  return rtc::scoped_ptr<Vad>(new VadImpl(aggressiveness));
 }
 
 }  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
index 171198b..1ef22f6 100644
--- a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
+++ b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
@@ -54,7 +54,8 @@
       num_cng_coefficients_(config.num_cng_coefficients),
       sid_frame_interval_ms_(config.sid_frame_interval_ms),
       last_frame_active_(true),
-      vad_(config.vad ? config.vad : new Vad(config.vad_mode)) {
+      vad_(config.vad ? rtc_make_scoped_ptr(config.vad)
+                      : CreateVad(config.vad_mode)) {
   CHECK(config.IsOk()) << "Invalid configuration.";
   cng_inst_ = CreateCngInst(SampleRateHz(), sid_frame_interval_ms_,
                             num_cng_coefficients_);
diff --git a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
index d7bc474..0b837a0 100644
--- a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
+++ b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
@@ -34,7 +34,7 @@
 class AudioEncoderCngTest : public ::testing::Test {
  protected:
   AudioEncoderCngTest()
-      : mock_vad_(new MockVad(Vad::kVadNormal)),
+      : mock_vad_(new MockVad),
         timestamp_(4711),
         num_audio_samples_10ms_(0),
         sample_rate_hz_(8000) {