OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
12 #include "webrtc/base/scoped_ptr.h" | 12 #include "webrtc/base/scoped_ptr.h" |
| 13 #include "webrtc/common_types.h" |
13 #include "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h
" | 14 #include "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h
" |
14 | 15 |
15 namespace webrtc { | 16 namespace webrtc { |
16 | 17 |
| 18 namespace { |
| 19 const CodecInst kOpusSettings = {105, "opus", 48000, 960, 1, 32000}; |
| 20 } // namespace |
| 21 |
17 class AudioEncoderOpusTest : public ::testing::Test { | 22 class AudioEncoderOpusTest : public ::testing::Test { |
18 protected: | 23 protected: |
19 // The constructor simply creates an Opus encoder with default configuration. | 24 void CreateCodec(int num_channels) { |
20 AudioEncoderOpusTest() | 25 codec_inst_.channels = num_channels; |
21 : opus_(new AudioEncoderOpus(AudioEncoderOpus::Config())) {} | 26 encoder_.reset(new AudioEncoderOpus(codec_inst_)); |
22 | 27 auto expected_app = |
23 // Repeatedly sets packet loss rates in the range [from, to], increasing by | 28 num_channels == 1 ? AudioEncoderOpus::kVoip : AudioEncoderOpus::kAudio; |
24 // 0.01 in each step. The function verifies that the actual loss rate is | 29 EXPECT_EQ(expected_app, encoder_->application()); |
25 // |expected_return|. | |
26 void TestSetPacketLossRate(double from, double to, double expected_return) { | |
27 ASSERT_TRUE(opus_); | |
28 for (double loss = from; loss <= to; | |
29 (to >= from) ? loss += 0.01 : loss -= 0.01) { | |
30 opus_->SetProjectedPacketLossRate(loss); | |
31 EXPECT_DOUBLE_EQ(expected_return, opus_->packet_loss_rate()); | |
32 } | |
33 } | 30 } |
34 | 31 |
35 rtc::scoped_ptr<AudioEncoderOpus> opus_; | 32 CodecInst codec_inst_ = kOpusSettings; |
| 33 rtc::scoped_ptr<AudioEncoderOpus> encoder_; |
36 }; | 34 }; |
37 | 35 |
| 36 TEST_F(AudioEncoderOpusTest, DefaultApplicationModeMono) { |
| 37 CreateCodec(1); |
| 38 } |
| 39 |
| 40 TEST_F(AudioEncoderOpusTest, DefaultApplicationModeStereo) { |
| 41 CreateCodec(2); |
| 42 } |
| 43 |
| 44 TEST_F(AudioEncoderOpusTest, ChangeApplicationMode) { |
| 45 CreateCodec(2); |
| 46 EXPECT_TRUE(encoder_->SetApplication(AudioEncoder::Application::kSpeech)); |
| 47 EXPECT_EQ(AudioEncoderOpus::kVoip, encoder_->application()); |
| 48 } |
| 49 |
| 50 TEST_F(AudioEncoderOpusTest, ResetWontChangeApplicationMode) { |
| 51 CreateCodec(2); |
| 52 |
| 53 // Trigger a reset. |
| 54 encoder_->Reset(); |
| 55 // Verify that the mode is still kAudio. |
| 56 EXPECT_EQ(AudioEncoderOpus::kAudio, encoder_->application()); |
| 57 |
| 58 // Now change to kVoip. |
| 59 EXPECT_TRUE(encoder_->SetApplication(AudioEncoder::Application::kSpeech)); |
| 60 EXPECT_EQ(AudioEncoderOpus::kVoip, encoder_->application()); |
| 61 |
| 62 // Trigger a reset again. |
| 63 encoder_->Reset(); |
| 64 // Verify that the mode is still kVoip. |
| 65 EXPECT_EQ(AudioEncoderOpus::kVoip, encoder_->application()); |
| 66 } |
| 67 |
| 68 TEST_F(AudioEncoderOpusTest, ToggleDtx) { |
| 69 CreateCodec(2); |
| 70 // Enable DTX |
| 71 EXPECT_TRUE(encoder_->SetDtx(true)); |
| 72 // Verify that the mode is still kAudio. |
| 73 EXPECT_EQ(AudioEncoderOpus::kAudio, encoder_->application()); |
| 74 // Turn off DTX. |
| 75 EXPECT_TRUE(encoder_->SetDtx(false)); |
| 76 } |
| 77 |
| 78 TEST_F(AudioEncoderOpusTest, SetBitrate) { |
| 79 CreateCodec(1); |
| 80 // Constants are replicated from audio_encoder_opus.cc. |
| 81 const int kMinBitrateBps = 500; |
| 82 const int kMaxBitrateBps = 512000; |
| 83 // Set a too low bitrate. |
| 84 encoder_->SetTargetBitrate(kMinBitrateBps - 1); |
| 85 EXPECT_EQ(kMinBitrateBps, encoder_->GetTargetBitrate()); |
| 86 // Set a too high bitrate. |
| 87 encoder_->SetTargetBitrate(kMaxBitrateBps + 1); |
| 88 EXPECT_EQ(kMaxBitrateBps, encoder_->GetTargetBitrate()); |
| 89 // Set the minimum rate. |
| 90 encoder_->SetTargetBitrate(kMinBitrateBps); |
| 91 EXPECT_EQ(kMinBitrateBps, encoder_->GetTargetBitrate()); |
| 92 // Set the maximum rate. |
| 93 encoder_->SetTargetBitrate(kMaxBitrateBps); |
| 94 EXPECT_EQ(kMaxBitrateBps, encoder_->GetTargetBitrate()); |
| 95 // Set rates from 1000 up to 32000 bps. |
| 96 for (int rate = 1000; rate <= 32000; rate += 1000) { |
| 97 encoder_->SetTargetBitrate(rate); |
| 98 EXPECT_EQ(rate, encoder_->GetTargetBitrate()); |
| 99 } |
| 100 } |
| 101 |
38 namespace { | 102 namespace { |
| 103 |
39 // These constants correspond to those used in | 104 // These constants correspond to those used in |
40 // AudioEncoderOpus::SetProjectedPacketLossRate. | 105 // AudioEncoderOpus::SetProjectedPacketLossRate. |
41 const double kPacketLossRate20 = 0.20; | 106 const double kPacketLossRate20 = 0.20; |
42 const double kPacketLossRate10 = 0.10; | 107 const double kPacketLossRate10 = 0.10; |
43 const double kPacketLossRate5 = 0.05; | 108 const double kPacketLossRate5 = 0.05; |
44 const double kPacketLossRate1 = 0.01; | 109 const double kPacketLossRate1 = 0.01; |
45 const double kLossRate20Margin = 0.02; | 110 const double kLossRate20Margin = 0.02; |
46 const double kLossRate10Margin = 0.01; | 111 const double kLossRate10Margin = 0.01; |
47 const double kLossRate5Margin = 0.01; | 112 const double kLossRate5Margin = 0.01; |
| 113 |
| 114 // Repeatedly sets packet loss rates in the range [from, to], increasing by |
| 115 // 0.01 in each step. The function verifies that the actual loss rate is |
| 116 // |expected_return|. |
| 117 void TestSetPacketLossRate(AudioEncoderOpus* encoder, |
| 118 double from, |
| 119 double to, |
| 120 double expected_return) { |
| 121 for (double loss = from; loss <= to; |
| 122 (to >= from) ? loss += 0.01 : loss -= 0.01) { |
| 123 encoder->SetProjectedPacketLossRate(loss); |
| 124 EXPECT_DOUBLE_EQ(expected_return, encoder->packet_loss_rate()); |
| 125 } |
| 126 } |
| 127 |
48 } // namespace | 128 } // namespace |
49 | 129 |
50 TEST_F(AudioEncoderOpusTest, PacketLossRateOptimized) { | 130 TEST_F(AudioEncoderOpusTest, PacketLossRateOptimized) { |
| 131 CreateCodec(1); |
| 132 |
51 // Note that the order of the following calls is critical. | 133 // Note that the order of the following calls is critical. |
52 TestSetPacketLossRate(0.0, 0.0, 0.0); | 134 TestSetPacketLossRate(encoder_.get(), 0.0, 0.0, 0.0); |
53 TestSetPacketLossRate(kPacketLossRate1, | 135 TestSetPacketLossRate(encoder_.get(), kPacketLossRate1, |
54 kPacketLossRate5 + kLossRate5Margin - 0.01, | 136 kPacketLossRate5 + kLossRate5Margin - 0.01, |
55 kPacketLossRate1); | 137 kPacketLossRate1); |
56 TestSetPacketLossRate(kPacketLossRate5 + kLossRate5Margin, | 138 TestSetPacketLossRate(encoder_.get(), kPacketLossRate5 + kLossRate5Margin, |
57 kPacketLossRate10 + kLossRate10Margin - 0.01, | 139 kPacketLossRate10 + kLossRate10Margin - 0.01, |
58 kPacketLossRate5); | 140 kPacketLossRate5); |
59 TestSetPacketLossRate(kPacketLossRate10 + kLossRate10Margin, | 141 TestSetPacketLossRate(encoder_.get(), kPacketLossRate10 + kLossRate10Margin, |
60 kPacketLossRate20 + kLossRate20Margin - 0.01, | 142 kPacketLossRate20 + kLossRate20Margin - 0.01, |
61 kPacketLossRate10); | 143 kPacketLossRate10); |
62 TestSetPacketLossRate(kPacketLossRate20 + kLossRate20Margin, | 144 TestSetPacketLossRate(encoder_.get(), kPacketLossRate20 + kLossRate20Margin, |
63 1.0, | 145 1.0, kPacketLossRate20); |
64 kPacketLossRate20); | 146 TestSetPacketLossRate(encoder_.get(), kPacketLossRate20 + kLossRate20Margin, |
65 TestSetPacketLossRate(kPacketLossRate20 + kLossRate20Margin, | |
66 kPacketLossRate20 - kLossRate20Margin, | 147 kPacketLossRate20 - kLossRate20Margin, |
67 kPacketLossRate20); | 148 kPacketLossRate20); |
68 TestSetPacketLossRate(kPacketLossRate20 - kLossRate20Margin - 0.01, | 149 TestSetPacketLossRate( |
69 kPacketLossRate10 - kLossRate10Margin, | 150 encoder_.get(), kPacketLossRate20 - kLossRate20Margin - 0.01, |
70 kPacketLossRate10); | 151 kPacketLossRate10 - kLossRate10Margin, kPacketLossRate10); |
71 TestSetPacketLossRate(kPacketLossRate10 - kLossRate10Margin - 0.01, | 152 TestSetPacketLossRate(encoder_.get(), |
72 kPacketLossRate5 - kLossRate5Margin, | 153 kPacketLossRate10 - kLossRate10Margin - 0.01, |
73 kPacketLossRate5); | 154 kPacketLossRate5 - kLossRate5Margin, kPacketLossRate5); |
74 TestSetPacketLossRate(kPacketLossRate5 - kLossRate5Margin - 0.01, | 155 TestSetPacketLossRate(encoder_.get(), |
75 kPacketLossRate1, | 156 kPacketLossRate5 - kLossRate5Margin - 0.01, |
76 kPacketLossRate1); | 157 kPacketLossRate1, kPacketLossRate1); |
77 TestSetPacketLossRate(0.0, 0.0, 0.0); | 158 TestSetPacketLossRate(encoder_.get(), 0.0, 0.0, 0.0); |
78 } | 159 } |
79 | 160 |
80 } // namespace webrtc | 161 } // namespace webrtc |
OLD | NEW |