1/* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include <stdio.h> 12#include <string> 13 14#include "webrtc/call/rtc_event_log.h" 15#include "webrtc/test/test_suite.h" 16#include "webrtc/test/testsupport/fileutils.h" 17#include "webrtc/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h" 18#include "webrtc/voice_engine/voice_engine_defines.h" 19 20class CodecTest : public AfterStreamingFixture { 21 protected: 22 void SetUp() { 23 memset(&codec_instance_, 0, sizeof(codec_instance_)); 24 } 25 26 void SetArbitrarySendCodec() { 27 // Just grab the first codec. 28 EXPECT_EQ(0, voe_codec_->GetCodec(0, codec_instance_)); 29 EXPECT_EQ(0, voe_codec_->SetSendCodec(channel_, codec_instance_)); 30 } 31 32 webrtc::CodecInst codec_instance_; 33}; 34 35static void SetRateIfILBC(webrtc::CodecInst* codec_instance, int packet_size) { 36 if (!_stricmp(codec_instance->plname, "ilbc")) { 37 if (packet_size == 160 || packet_size == 320) { 38 codec_instance->rate = 15200; 39 } else { 40 codec_instance->rate = 13300; 41 } 42 } 43} 44 45static bool IsNotViableSendCodec(const char* codec_name) { 46 return !_stricmp(codec_name, "CN") || 47 !_stricmp(codec_name, "telephone-event") || 48 !_stricmp(codec_name, "red"); 49} 50 51TEST_F(CodecTest, PcmuIsDefaultCodecAndHasTheRightValues) { 52 EXPECT_EQ(0, voe_codec_->GetSendCodec(channel_, codec_instance_)); 53 EXPECT_EQ(1u, codec_instance_.channels); 54 EXPECT_EQ(160, codec_instance_.pacsize); 55 EXPECT_EQ(8000, codec_instance_.plfreq); 56 EXPECT_EQ(0, codec_instance_.pltype); 57 EXPECT_EQ(64000, codec_instance_.rate); 58 EXPECT_STRCASEEQ("PCMU", codec_instance_.plname); 59} 60 61TEST_F(CodecTest, VoiceActivityDetectionIsOffByDefault) { 62 bool vad_enabled = false; 63 bool dtx_disabled = false; 64 webrtc::VadModes vad_mode = webrtc::kVadAggressiveMid; 65 66 voe_codec_->GetVADStatus(channel_, vad_enabled, vad_mode, dtx_disabled); 67 68 EXPECT_FALSE(vad_enabled); 69 EXPECT_TRUE(dtx_disabled); 70 EXPECT_EQ(webrtc::kVadConventional, vad_mode); 71} 72 73TEST_F(CodecTest, VoiceActivityDetectionCanBeEnabled) { 74 EXPECT_EQ(0, voe_codec_->SetVADStatus(channel_, true)); 75 76 bool vad_enabled = false; 77 bool dtx_disabled = false; 78 webrtc::VadModes vad_mode = webrtc::kVadAggressiveMid; 79 80 voe_codec_->GetVADStatus(channel_, vad_enabled, vad_mode, dtx_disabled); 81 82 EXPECT_TRUE(vad_enabled); 83 EXPECT_EQ(webrtc::kVadConventional, vad_mode); 84 EXPECT_FALSE(dtx_disabled); 85} 86 87TEST_F(CodecTest, VoiceActivityDetectionTypeSettingsCanBeChanged) { 88 bool vad_enabled = false; 89 bool dtx_disabled = false; 90 webrtc::VadModes vad_mode = webrtc::kVadAggressiveMid; 91 92 EXPECT_EQ(0, voe_codec_->SetVADStatus( 93 channel_, true, webrtc::kVadAggressiveLow, false)); 94 EXPECT_EQ(0, voe_codec_->GetVADStatus( 95 channel_, vad_enabled, vad_mode, dtx_disabled)); 96 EXPECT_EQ(vad_mode, webrtc::kVadAggressiveLow); 97 EXPECT_FALSE(dtx_disabled); 98 99 EXPECT_EQ(0, voe_codec_->SetVADStatus( 100 channel_, true, webrtc::kVadAggressiveMid, false)); 101 EXPECT_EQ(0, voe_codec_->GetVADStatus( 102 channel_, vad_enabled, vad_mode, dtx_disabled)); 103 EXPECT_EQ(vad_mode, webrtc::kVadAggressiveMid); 104 EXPECT_FALSE(dtx_disabled); 105 106 // The fourth argument is the DTX disable flag, which is always supposed to 107 // be false. 108 EXPECT_EQ(0, voe_codec_->SetVADStatus(channel_, true, 109 webrtc::kVadAggressiveHigh, false)); 110 EXPECT_EQ(0, voe_codec_->GetVADStatus( 111 channel_, vad_enabled, vad_mode, dtx_disabled)); 112 EXPECT_EQ(vad_mode, webrtc::kVadAggressiveHigh); 113 EXPECT_FALSE(dtx_disabled); 114 115 EXPECT_EQ(0, voe_codec_->SetVADStatus(channel_, true, 116 webrtc::kVadConventional, false)); 117 EXPECT_EQ(0, voe_codec_->GetVADStatus( 118 channel_, vad_enabled, vad_mode, dtx_disabled)); 119 EXPECT_EQ(vad_mode, webrtc::kVadConventional); 120} 121 122TEST_F(CodecTest, VoiceActivityDetectionCanBeTurnedOff) { 123 EXPECT_EQ(0, voe_codec_->SetVADStatus(channel_, true)); 124 125 // VAD is always on when DTX is on, so we need to turn off DTX too. 126 EXPECT_EQ(0, voe_codec_->SetVADStatus( 127 channel_, false, webrtc::kVadConventional, true)); 128 129 bool vad_enabled = false; 130 bool dtx_disabled = false; 131 webrtc::VadModes vad_mode = webrtc::kVadAggressiveMid; 132 133 voe_codec_->GetVADStatus(channel_, vad_enabled, vad_mode, dtx_disabled); 134 135 EXPECT_FALSE(vad_enabled); 136 EXPECT_TRUE(dtx_disabled); 137 EXPECT_EQ(webrtc::kVadConventional, vad_mode); 138} 139 140TEST_F(CodecTest, OpusMaxPlaybackRateCanBeSet) { 141 for (int i = 0; i < voe_codec_->NumOfCodecs(); ++i) { 142 voe_codec_->GetCodec(i, codec_instance_); 143 if (_stricmp("opus", codec_instance_.plname)) { 144 continue; 145 } 146 voe_codec_->SetSendCodec(channel_, codec_instance_); 147 // SetOpusMaxPlaybackRate can handle any integer as the bandwidth. Following 148 // tests some most commonly used numbers. 149 EXPECT_EQ(0, voe_codec_->SetOpusMaxPlaybackRate(channel_, 48000)); 150 EXPECT_EQ(0, voe_codec_->SetOpusMaxPlaybackRate(channel_, 32000)); 151 EXPECT_EQ(0, voe_codec_->SetOpusMaxPlaybackRate(channel_, 16000)); 152 EXPECT_EQ(0, voe_codec_->SetOpusMaxPlaybackRate(channel_, 8000)); 153 } 154} 155 156TEST_F(CodecTest, OpusDtxCanBeSetForOpus) { 157 for (int i = 0; i < voe_codec_->NumOfCodecs(); ++i) { 158 voe_codec_->GetCodec(i, codec_instance_); 159 if (_stricmp("opus", codec_instance_.plname)) { 160 continue; 161 } 162 voe_codec_->SetSendCodec(channel_, codec_instance_); 163 EXPECT_EQ(0, voe_codec_->SetOpusDtx(channel_, false)); 164 EXPECT_EQ(0, voe_codec_->SetOpusDtx(channel_, true)); 165 } 166} 167 168TEST_F(CodecTest, OpusDtxCannotBeSetForNonOpus) { 169 for (int i = 0; i < voe_codec_->NumOfCodecs(); ++i) { 170 voe_codec_->GetCodec(i, codec_instance_); 171 if (!_stricmp("opus", codec_instance_.plname)) { 172 continue; 173 } 174 voe_codec_->SetSendCodec(channel_, codec_instance_); 175 EXPECT_EQ(-1, voe_codec_->SetOpusDtx(channel_, true)); 176 } 177} 178 179#ifdef ENABLE_RTC_EVENT_LOG 180TEST_F(CodecTest, RtcEventLogIntegrationTest) { 181 webrtc::RtcEventLog* event_log = voe_codec_->GetEventLog(); 182 ASSERT_TRUE(event_log); 183 184 // Find the name of the current test, in order to use it as a temporary 185 // filename. 186 auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); 187 const std::string temp_filename = webrtc::test::OutputPath() + 188 test_info->test_case_name() + 189 test_info->name(); 190 // Create a log file. 191 event_log->StartLogging(temp_filename, 1000); 192 event_log->StopLogging(); 193 194 // Check if the file has been created. 195 FILE* event_file = fopen(temp_filename.c_str(), "r"); 196 ASSERT_TRUE(event_file); 197 fclose(event_file); 198 // Remove the temporary file. 199 remove(temp_filename.c_str()); 200} 201#endif // ENABLE_RTC_EVENT_LOG 202 203// TODO(xians, phoglund): Re-enable when issue 372 is resolved. 204TEST_F(CodecTest, DISABLED_ManualVerifySendCodecsForAllPacketSizes) { 205 for (int i = 0; i < voe_codec_->NumOfCodecs(); ++i) { 206 voe_codec_->GetCodec(i, codec_instance_); 207 if (IsNotViableSendCodec(codec_instance_.plname)) { 208 TEST_LOG("Skipping %s.\n", codec_instance_.plname); 209 continue; 210 } 211 EXPECT_NE(-1, codec_instance_.pltype) << 212 "The codec database should suggest a payload type."; 213 214 // Test with default packet size: 215 TEST_LOG("%s (pt=%d): default packet size(%d), accepts sizes ", 216 codec_instance_.plname, codec_instance_.pltype, 217 codec_instance_.pacsize); 218 voe_codec_->SetSendCodec(channel_, codec_instance_); 219 Sleep(CODEC_TEST_TIME); 220 221 // Now test other reasonable packet sizes: 222 bool at_least_one_succeeded = false; 223 for (int packet_size = 80; packet_size < 1000; packet_size += 80) { 224 SetRateIfILBC(&codec_instance_, packet_size); 225 codec_instance_.pacsize = packet_size; 226 227 if (voe_codec_->SetSendCodec(channel_, codec_instance_) != -1) { 228 // Note that it's fine for SetSendCodec to fail - what packet sizes 229 // it accepts depends on the codec. It should accept one at minimum. 230 TEST_LOG("%d ", packet_size); 231 TEST_LOG_FLUSH; 232 at_least_one_succeeded = true; 233 Sleep(CODEC_TEST_TIME); 234 } 235 } 236 TEST_LOG("\n"); 237 EXPECT_TRUE(at_least_one_succeeded); 238 } 239} 240