ACM CodecOwner: Test that we reset speech encoder when enabling CNG or RED

If we don't, we'll end up crashing if they're enabled when the speech
encoder is in the middle of encoding a packet, since CNG and RED
assume that the speech encoder starts out with an empty buffer
(because they need to be in sync with it).

BUG=chromium:490368

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

Cr-Commit-Position: refs/heads/master@{#9917}
diff --git a/webrtc/modules/audio_coding/main/acm2/codec_owner_unittest.cc b/webrtc/modules/audio_coding/main/acm2/codec_owner_unittest.cc
index ec1bb0d..9c17073 100644
--- a/webrtc/modules/audio_coding/main/acm2/codec_owner_unittest.cc
+++ b/webrtc/modules/audio_coding/main/acm2/codec_owner_unittest.cc
@@ -56,6 +56,41 @@
                 encoded_info.send_even_if_empty);
   }
 
+  // Verify that the speech encoder's Reset method is called when CNG or RED
+  // (or both) are switched on, but not when they're switched off.
+  void TestCngAndRedResetSpeechEncoder(bool use_cng, bool use_red) {
+    MockAudioEncoder speech_encoder;
+    EXPECT_CALL(speech_encoder, NumChannels())
+        .WillRepeatedly(Return(1));
+    EXPECT_CALL(speech_encoder, Max10MsFramesInAPacket())
+        .WillRepeatedly(Return(2));
+    EXPECT_CALL(speech_encoder, SampleRateHz())
+        .WillRepeatedly(Return(8000));
+    {
+      InSequence s;
+      EXPECT_CALL(speech_encoder, Mark("start off"));
+      EXPECT_CALL(speech_encoder, Mark("switch on"));
+      if (use_cng || use_red)
+        EXPECT_CALL(speech_encoder, Reset());
+      EXPECT_CALL(speech_encoder, Mark("start on"));
+      if (use_cng || use_red)
+        EXPECT_CALL(speech_encoder, Reset());
+      EXPECT_CALL(speech_encoder, Mark("switch off"));
+      EXPECT_CALL(speech_encoder, Die());
+    }
+
+    int cng_pt = use_cng ? 17 : -1;
+    int red_pt = use_red ? 19 : -1;
+    speech_encoder.Mark("start off");
+    codec_owner_.SetEncoders(&speech_encoder, -1, VADNormal, -1);
+    speech_encoder.Mark("switch on");
+    codec_owner_.ChangeCngAndRed(cng_pt, VADNormal, red_pt);
+    speech_encoder.Mark("start on");
+    codec_owner_.SetEncoders(&speech_encoder, cng_pt, VADNormal, red_pt);
+    speech_encoder.Mark("switch off");
+    codec_owner_.ChangeCngAndRed(-1, VADNormal, -1);
+  }
+
   CodecOwner codec_owner_;
   uint32_t timestamp_;
 };
@@ -145,5 +180,21 @@
   EXPECT_EQ(2u, info.encoded_timestamp);
 }
 
+TEST_F(CodecOwnerTest, CngResetsSpeechEncoder) {
+  TestCngAndRedResetSpeechEncoder(true, false);
+}
+
+TEST_F(CodecOwnerTest, RedResetsSpeechEncoder) {
+  TestCngAndRedResetSpeechEncoder(false, true);
+}
+
+TEST_F(CodecOwnerTest, CngAndRedResetsSpeechEncoder) {
+  TestCngAndRedResetSpeechEncoder(true, true);
+}
+
+TEST_F(CodecOwnerTest, NoCngAndRedNoSpeechEncoderReset) {
+  TestCngAndRedResetSpeechEncoder(false, false);
+}
+
 }  // namespace acm2
 }  // namespace webrtc