Add new AcmGenericCodecTest and verify output from Encode function
The test specifically verifies that the output is as expected when
DTX/CNG is used.
COAUTHOR=kwiberg@webrtc.org
R=minyue@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/38219004
Cr-Commit-Position: refs/heads/master@{#8497}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8497 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec_test.cc b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec_test.cc
new file mode 100644
index 0000000..1b8113c
--- /dev/null
+++ b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec_test.cc
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/safe_conversions.h"
+#include "webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h"
+
+namespace webrtc {
+namespace acm2 {
+
+namespace {
+const int kDataLengthSamples = 80;
+const int16_t kZeroData[kDataLengthSamples] = {0};
+const CodecInst kDefaultCodecInst =
+ {0, "pcmu", 8000, 2 * kDataLengthSamples, 1, 64000};
+const int kCngPt = 13;
+const int kNoCngPt = 255;
+const int kRedPt = 255; // Not using RED in this test.
+} // namespace
+
+class AcmGenericCodecTest : public ::testing::Test {
+ protected:
+ AcmGenericCodecTest() : timestamp_(0) {
+ acm_codec_params_ = {kDefaultCodecInst, true, true, VADNormal};
+ }
+
+ void CreateCodec() {
+ codec_.reset(new ACMGenericCodec(acm_codec_params_.codec_inst, kCngPt,
+ kNoCngPt, kNoCngPt, kNoCngPt,
+ false /* enable RED */, kRedPt));
+ ASSERT_TRUE(codec_);
+ ASSERT_EQ(0, codec_->InitEncoder(&acm_codec_params_, true));
+ }
+
+ void AddData() {
+ EXPECT_EQ(
+ 0, codec_->Add10MsData(timestamp_, kZeroData, kDataLengthSamples, 1));
+ timestamp_ += kDataLengthSamples;
+ }
+
+ void EncodeAndVerify(int expected_return_val,
+ size_t expected_out_length,
+ uint32_t expected_timestamp,
+ WebRtcACMEncodingType expected_encoding_type,
+ int expected_payload_type,
+ int expected_send_even_if_empty) {
+ uint8_t out[kDataLengthSamples];
+ int16_t out_length;
+ uint32_t out_timestamp;
+ WebRtcACMEncodingType encoding_type;
+ AudioEncoder::EncodedInfo encoded_info;
+ EXPECT_EQ(expected_return_val,
+ codec_->Encode(out, &out_length, &out_timestamp, &encoding_type,
+ &encoded_info));
+ EXPECT_EQ(expected_timestamp, out_timestamp);
+ EXPECT_EQ(expected_encoding_type, encoding_type);
+ EXPECT_TRUE(encoded_info.redundant.empty());
+ EXPECT_EQ(expected_out_length, encoded_info.encoded_bytes);
+ EXPECT_EQ(expected_out_length, rtc::checked_cast<size_t>(out_length));
+ EXPECT_EQ(expected_timestamp, encoded_info.encoded_timestamp);
+ if (expected_payload_type >= 0)
+ EXPECT_EQ(expected_payload_type, encoded_info.payload_type);
+ if (expected_send_even_if_empty >= 0)
+ EXPECT_EQ(static_cast<bool>(expected_send_even_if_empty),
+ encoded_info.send_even_if_empty);
+ }
+
+ WebRtcACMCodecParams acm_codec_params_;
+ scoped_ptr<ACMGenericCodec> codec_;
+ uint32_t timestamp_;
+};
+
+// This test verifies that CNG frames are delivered as expected. Since the frame
+// size is set to 20 ms, we expect the first encode call to produce no output
+// (which is signaled as 0 bytes output of type kNoEncoding). The next encode
+// call should produce one SID frame of 9 bytes. The third call should not
+// result in any output (just like the first one). The fourth and final encode
+// call should produce an "empty frame", which is like no output, but with the
+// return value from the encode function being 1. (The reason to produce an
+// empty frame is to drive sending of DTMF packets in the RTP/RTCP module.)
+TEST_F(AcmGenericCodecTest, VerifyCngFrames) {
+ CreateCodec();
+ uint32_t expected_timestamp = timestamp_;
+ // Verify no frame.
+ AddData();
+ {
+ SCOPED_TRACE("First encoding");
+ EncodeAndVerify(0, 0, expected_timestamp, kNoEncoding, -1, -1);
+ }
+
+ // Verify SID frame delivered.
+ AddData();
+ {
+ SCOPED_TRACE("Second encoding");
+ EncodeAndVerify(9, 9, expected_timestamp, kPassiveDTXNB, kCngPt, 1);
+ }
+
+ // Verify no frame.
+ AddData();
+ {
+ SCOPED_TRACE("Third encoding");
+ EncodeAndVerify(0, 0, expected_timestamp, kNoEncoding, -1, -1);
+ }
+
+ // Verify NoEncoding.
+ AddData();
+ expected_timestamp += 2 * kDataLengthSamples;
+ {
+ SCOPED_TRACE("Fourth encoding");
+ EncodeAndVerify(1, 0, expected_timestamp, kNoEncoding, kCngPt, 1);
+ }
+}
+
+} // namespace acm2
+} // namespace webrtc
diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp
index 5b78e7a..8bb3745 100644
--- a/webrtc/modules/modules.gyp
+++ b/webrtc/modules/modules.gyp
@@ -91,6 +91,7 @@
],
'sources': [
'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc',
+ 'audio_coding/main/acm2/acm_generic_codec_test.cc',
'audio_coding/main/acm2/acm_generic_codec_opus_test.cc',
'audio_coding/main/acm2/acm_receiver_unittest.cc',
'audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc',