| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2014 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 <string.h> | |
| 12 #include <vector> | |
| 13 | |
| 14 #include "testing/gtest/include/gtest/gtest.h" | |
| 15 #include "webrtc/base/checks.h" | |
| 16 #include "webrtc/base/md5digest.h" | |
| 17 #include "webrtc/base/scoped_ptr.h" | |
| 18 #include "webrtc/base/thread_annotations.h" | |
| 19 #include "webrtc/modules/audio_coding/main/acm2/acm_receive_test.h" | |
| 20 #include "webrtc/modules/audio_coding/main/acm2/acm_send_test.h" | |
| 21 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" | |
| 22 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedef
s.h" | |
| 23 #include "webrtc/modules/audio_coding/neteq/tools/audio_checksum.h" | |
| 24 #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" | |
| 25 #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" | |
| 26 #include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h" | |
| 27 #include "webrtc/modules/audio_coding/neteq/tools/packet.h" | |
| 28 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" | |
| 29 #include "webrtc/modules/interface/module_common_types.h" | |
| 30 #include "webrtc/system_wrappers/interface/clock.h" | |
| 31 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" | |
| 32 #include "webrtc/system_wrappers/interface/event_wrapper.h" | |
| 33 #include "webrtc/system_wrappers/interface/sleep.h" | |
| 34 #include "webrtc/system_wrappers/interface/thread_wrapper.h" | |
| 35 #include "webrtc/test/testsupport/fileutils.h" | |
| 36 #include "webrtc/test/testsupport/gtest_disable.h" | |
| 37 | |
| 38 namespace webrtc { | |
| 39 | |
| 40 const int kSampleRateHz = 16000; | |
| 41 const int kNumSamples10ms = kSampleRateHz / 100; | |
| 42 const int kFrameSizeMs = 10; // Multiple of 10. | |
| 43 const int kFrameSizeSamples = kFrameSizeMs / 10 * kNumSamples10ms; | |
| 44 const size_t kPayloadSizeBytes = kFrameSizeSamples * sizeof(int16_t); | |
| 45 const uint8_t kPayloadType = 111; | |
| 46 | |
| 47 class RtpUtility { | |
| 48 public: | |
| 49 RtpUtility(int samples_per_packet, uint8_t payload_type) | |
| 50 : samples_per_packet_(samples_per_packet), payload_type_(payload_type) {} | |
| 51 | |
| 52 virtual ~RtpUtility() {} | |
| 53 | |
| 54 void Populate(WebRtcRTPHeader* rtp_header) { | |
| 55 rtp_header->header.sequenceNumber = 0xABCD; | |
| 56 rtp_header->header.timestamp = 0xABCDEF01; | |
| 57 rtp_header->header.payloadType = payload_type_; | |
| 58 rtp_header->header.markerBit = false; | |
| 59 rtp_header->header.ssrc = 0x1234; | |
| 60 rtp_header->header.numCSRCs = 0; | |
| 61 rtp_header->frameType = kAudioFrameSpeech; | |
| 62 | |
| 63 rtp_header->header.payload_type_frequency = kSampleRateHz; | |
| 64 rtp_header->type.Audio.channel = 1; | |
| 65 rtp_header->type.Audio.isCNG = false; | |
| 66 } | |
| 67 | |
| 68 void Forward(WebRtcRTPHeader* rtp_header) { | |
| 69 ++rtp_header->header.sequenceNumber; | |
| 70 rtp_header->header.timestamp += samples_per_packet_; | |
| 71 } | |
| 72 | |
| 73 private: | |
| 74 int samples_per_packet_; | |
| 75 uint8_t payload_type_; | |
| 76 }; | |
| 77 | |
| 78 class PacketizationCallbackStub : public AudioPacketizationCallback { | |
| 79 public: | |
| 80 PacketizationCallbackStub() | |
| 81 : num_calls_(0), | |
| 82 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()) {} | |
| 83 | |
| 84 int32_t SendData(FrameType frame_type, | |
| 85 uint8_t payload_type, | |
| 86 uint32_t timestamp, | |
| 87 const uint8_t* payload_data, | |
| 88 size_t payload_len_bytes, | |
| 89 const RTPFragmentationHeader* fragmentation) override { | |
| 90 CriticalSectionScoped lock(crit_sect_.get()); | |
| 91 ++num_calls_; | |
| 92 last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes); | |
| 93 return 0; | |
| 94 } | |
| 95 | |
| 96 int num_calls() const { | |
| 97 CriticalSectionScoped lock(crit_sect_.get()); | |
| 98 return num_calls_; | |
| 99 } | |
| 100 | |
| 101 int last_payload_len_bytes() const { | |
| 102 CriticalSectionScoped lock(crit_sect_.get()); | |
| 103 return last_payload_vec_.size(); | |
| 104 } | |
| 105 | |
| 106 void SwapBuffers(std::vector<uint8_t>* payload) { | |
| 107 CriticalSectionScoped lock(crit_sect_.get()); | |
| 108 last_payload_vec_.swap(*payload); | |
| 109 } | |
| 110 | |
| 111 private: | |
| 112 int num_calls_ GUARDED_BY(crit_sect_); | |
| 113 std::vector<uint8_t> last_payload_vec_ GUARDED_BY(crit_sect_); | |
| 114 const rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; | |
| 115 }; | |
| 116 | |
| 117 class AudioCodingModuleTest : public ::testing::Test { | |
| 118 protected: | |
| 119 AudioCodingModuleTest() | |
| 120 : rtp_utility_(new RtpUtility(kFrameSizeSamples, kPayloadType)) { | |
| 121 config_.transport = &packet_cb_; | |
| 122 } | |
| 123 | |
| 124 ~AudioCodingModuleTest() {} | |
| 125 | |
| 126 void TearDown() override {} | |
| 127 | |
| 128 void SetUp() override { | |
| 129 rtp_utility_->Populate(&rtp_header_); | |
| 130 | |
| 131 input_frame_.sample_rate_hz_ = kSampleRateHz; | |
| 132 input_frame_.num_channels_ = 1; | |
| 133 input_frame_.samples_per_channel_ = kSampleRateHz * 10 / 1000; // 10 ms. | |
| 134 static_assert(kSampleRateHz * 10 / 1000 <= AudioFrame::kMaxDataSizeSamples, | |
| 135 "audio frame too small"); | |
| 136 memset(input_frame_.data_, | |
| 137 0, | |
| 138 input_frame_.samples_per_channel_ * sizeof(input_frame_.data_[0])); | |
| 139 } | |
| 140 | |
| 141 void CreateAcm() { | |
| 142 acm_.reset(AudioCoding::Create(config_)); | |
| 143 ASSERT_TRUE(acm_.get() != NULL); | |
| 144 RegisterCodec(); | |
| 145 } | |
| 146 | |
| 147 virtual void RegisterCodec() { | |
| 148 // Register L16 codec in ACM. | |
| 149 int codec_type = acm2::ACMCodecDB::kNone; | |
| 150 switch (kSampleRateHz) { | |
| 151 case 8000: | |
| 152 codec_type = acm2::ACMCodecDB::kPCM16B; | |
| 153 break; | |
| 154 case 16000: | |
| 155 codec_type = acm2::ACMCodecDB::kPCM16Bwb; | |
| 156 break; | |
| 157 case 32000: | |
| 158 codec_type = acm2::ACMCodecDB::kPCM16Bswb32kHz; | |
| 159 break; | |
| 160 default: | |
| 161 FATAL() << "Sample rate not supported in this test."; | |
| 162 } | |
| 163 ASSERT_TRUE(acm_->RegisterSendCodec(codec_type, kPayloadType)); | |
| 164 ASSERT_TRUE(acm_->RegisterReceiveCodec(codec_type, kPayloadType)); | |
| 165 } | |
| 166 | |
| 167 virtual void InsertPacketAndPullAudio() { | |
| 168 InsertPacket(); | |
| 169 PullAudio(); | |
| 170 } | |
| 171 | |
| 172 virtual void InsertPacket() { | |
| 173 const uint8_t kPayload[kPayloadSizeBytes] = {0}; | |
| 174 ASSERT_TRUE(acm_->InsertPacket(kPayload, kPayloadSizeBytes, rtp_header_)); | |
| 175 rtp_utility_->Forward(&rtp_header_); | |
| 176 } | |
| 177 | |
| 178 virtual void PullAudio() { | |
| 179 AudioFrame audio_frame; | |
| 180 ASSERT_TRUE(acm_->Get10MsAudio(&audio_frame)); | |
| 181 } | |
| 182 | |
| 183 virtual void InsertAudio() { | |
| 184 int encoded_bytes = acm_->Add10MsAudio(input_frame_); | |
| 185 ASSERT_GE(encoded_bytes, 0); | |
| 186 input_frame_.timestamp_ += kNumSamples10ms; | |
| 187 } | |
| 188 | |
| 189 AudioCoding::Config config_; | |
| 190 rtc::scoped_ptr<RtpUtility> rtp_utility_; | |
| 191 rtc::scoped_ptr<AudioCoding> acm_; | |
| 192 PacketizationCallbackStub packet_cb_; | |
| 193 WebRtcRTPHeader rtp_header_; | |
| 194 AudioFrame input_frame_; | |
| 195 }; | |
| 196 | |
| 197 // Check if the statistics are initialized correctly. Before any call to ACM | |
| 198 // all fields have to be zero. | |
| 199 TEST_F(AudioCodingModuleTest, DISABLED_ON_ANDROID(InitializedToZero)) { | |
| 200 CreateAcm(); | |
| 201 AudioDecodingCallStats stats; | |
| 202 acm_->GetDecodingCallStatistics(&stats); | |
| 203 EXPECT_EQ(0, stats.calls_to_neteq); | |
| 204 EXPECT_EQ(0, stats.calls_to_silence_generator); | |
| 205 EXPECT_EQ(0, stats.decoded_normal); | |
| 206 EXPECT_EQ(0, stats.decoded_cng); | |
| 207 EXPECT_EQ(0, stats.decoded_plc); | |
| 208 EXPECT_EQ(0, stats.decoded_plc_cng); | |
| 209 } | |
| 210 | |
| 211 // Apply an initial playout delay. Calls to AudioCodingModule::PlayoutData10ms() | |
| 212 // should result in generating silence, check the associated field. | |
| 213 TEST_F(AudioCodingModuleTest, DISABLED_ON_ANDROID(SilenceGeneratorCalled)) { | |
| 214 const int kInitialDelay = 100; | |
| 215 config_.initial_playout_delay_ms = kInitialDelay; | |
| 216 CreateAcm(); | |
| 217 AudioDecodingCallStats stats; | |
| 218 | |
| 219 int num_calls = 0; | |
| 220 for (int time_ms = 0; time_ms < kInitialDelay; | |
| 221 time_ms += kFrameSizeMs, ++num_calls) { | |
| 222 InsertPacketAndPullAudio(); | |
| 223 } | |
| 224 acm_->GetDecodingCallStatistics(&stats); | |
| 225 EXPECT_EQ(0, stats.calls_to_neteq); | |
| 226 EXPECT_EQ(num_calls, stats.calls_to_silence_generator); | |
| 227 EXPECT_EQ(0, stats.decoded_normal); | |
| 228 EXPECT_EQ(0, stats.decoded_cng); | |
| 229 EXPECT_EQ(0, stats.decoded_plc); | |
| 230 EXPECT_EQ(0, stats.decoded_plc_cng); | |
| 231 } | |
| 232 | |
| 233 // Insert some packets and pull audio. Check statistics are valid. Then, | |
| 234 // simulate packet loss and check if PLC and PLC-to-CNG statistics are | |
| 235 // correctly updated. | |
| 236 TEST_F(AudioCodingModuleTest, DISABLED_ON_ANDROID(NetEqCalls)) { | |
| 237 CreateAcm(); | |
| 238 AudioDecodingCallStats stats; | |
| 239 const int kNumNormalCalls = 10; | |
| 240 | |
| 241 for (int num_calls = 0; num_calls < kNumNormalCalls; ++num_calls) { | |
| 242 InsertPacketAndPullAudio(); | |
| 243 } | |
| 244 acm_->GetDecodingCallStatistics(&stats); | |
| 245 EXPECT_EQ(kNumNormalCalls, stats.calls_to_neteq); | |
| 246 EXPECT_EQ(0, stats.calls_to_silence_generator); | |
| 247 EXPECT_EQ(kNumNormalCalls, stats.decoded_normal); | |
| 248 EXPECT_EQ(0, stats.decoded_cng); | |
| 249 EXPECT_EQ(0, stats.decoded_plc); | |
| 250 EXPECT_EQ(0, stats.decoded_plc_cng); | |
| 251 | |
| 252 const int kNumPlc = 3; | |
| 253 const int kNumPlcCng = 5; | |
| 254 | |
| 255 // Simulate packet-loss. NetEq first performs PLC then PLC fades to CNG. | |
| 256 for (int n = 0; n < kNumPlc + kNumPlcCng; ++n) { | |
| 257 PullAudio(); | |
| 258 } | |
| 259 acm_->GetDecodingCallStatistics(&stats); | |
| 260 EXPECT_EQ(kNumNormalCalls + kNumPlc + kNumPlcCng, stats.calls_to_neteq); | |
| 261 EXPECT_EQ(0, stats.calls_to_silence_generator); | |
| 262 EXPECT_EQ(kNumNormalCalls, stats.decoded_normal); | |
| 263 EXPECT_EQ(0, stats.decoded_cng); | |
| 264 EXPECT_EQ(kNumPlc, stats.decoded_plc); | |
| 265 EXPECT_EQ(kNumPlcCng, stats.decoded_plc_cng); | |
| 266 } | |
| 267 | |
| 268 TEST_F(AudioCodingModuleTest, VerifyOutputFrame) { | |
| 269 CreateAcm(); | |
| 270 AudioFrame audio_frame; | |
| 271 const int kSampleRateHz = 32000; | |
| 272 EXPECT_TRUE(acm_->Get10MsAudio(&audio_frame)); | |
| 273 EXPECT_EQ(0u, audio_frame.timestamp_); | |
| 274 EXPECT_GT(audio_frame.num_channels_, 0); | |
| 275 EXPECT_EQ(static_cast<size_t>(kSampleRateHz / 100), | |
| 276 audio_frame.samples_per_channel_); | |
| 277 EXPECT_EQ(kSampleRateHz, audio_frame.sample_rate_hz_); | |
| 278 } | |
| 279 | |
| 280 // A multi-threaded test for ACM. This base class is using the PCM16b 16 kHz | |
| 281 // codec, while the derive class AcmIsacMtTest is using iSAC. | |
| 282 class AudioCodingModuleMtTest : public AudioCodingModuleTest { | |
| 283 protected: | |
| 284 static const int kNumPackets = 500; | |
| 285 static const int kNumPullCalls = 500; | |
| 286 | |
| 287 AudioCodingModuleMtTest() | |
| 288 : AudioCodingModuleTest(), | |
| 289 send_thread_(ThreadWrapper::CreateThread(CbSendThread, this, "send")), | |
| 290 insert_packet_thread_(ThreadWrapper::CreateThread( | |
| 291 CbInsertPacketThread, this, "insert_packet")), | |
| 292 pull_audio_thread_(ThreadWrapper::CreateThread( | |
| 293 CbPullAudioThread, this, "pull_audio")), | |
| 294 test_complete_(EventWrapper::Create()), | |
| 295 send_count_(0), | |
| 296 insert_packet_count_(0), | |
| 297 pull_audio_count_(0), | |
| 298 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), | |
| 299 next_insert_packet_time_ms_(0), | |
| 300 fake_clock_(new SimulatedClock(0)) { | |
| 301 config_.clock = fake_clock_.get(); | |
| 302 } | |
| 303 | |
| 304 void SetUp() override { | |
| 305 AudioCodingModuleTest::SetUp(); | |
| 306 CreateAcm(); | |
| 307 StartThreads(); | |
| 308 } | |
| 309 | |
| 310 void StartThreads() { | |
| 311 ASSERT_TRUE(send_thread_->Start()); | |
| 312 send_thread_->SetPriority(kRealtimePriority); | |
| 313 ASSERT_TRUE(insert_packet_thread_->Start()); | |
| 314 insert_packet_thread_->SetPriority(kRealtimePriority); | |
| 315 ASSERT_TRUE(pull_audio_thread_->Start()); | |
| 316 pull_audio_thread_->SetPriority(kRealtimePriority); | |
| 317 } | |
| 318 | |
| 319 void TearDown() override { | |
| 320 AudioCodingModuleTest::TearDown(); | |
| 321 pull_audio_thread_->Stop(); | |
| 322 send_thread_->Stop(); | |
| 323 insert_packet_thread_->Stop(); | |
| 324 } | |
| 325 | |
| 326 EventTypeWrapper RunTest() { | |
| 327 return test_complete_->Wait(10 * 60 * 1000); // 10 minutes' timeout. | |
| 328 } | |
| 329 | |
| 330 virtual bool TestDone() { | |
| 331 if (packet_cb_.num_calls() > kNumPackets) { | |
| 332 CriticalSectionScoped lock(crit_sect_.get()); | |
| 333 if (pull_audio_count_ > kNumPullCalls) { | |
| 334 // Both conditions for completion are met. End the test. | |
| 335 return true; | |
| 336 } | |
| 337 } | |
| 338 return false; | |
| 339 } | |
| 340 | |
| 341 static bool CbSendThread(void* context) { | |
| 342 return reinterpret_cast<AudioCodingModuleMtTest*>(context)->CbSendImpl(); | |
| 343 } | |
| 344 | |
| 345 // The send thread doesn't have to care about the current simulated time, | |
| 346 // since only the AcmReceiver is using the clock. | |
| 347 bool CbSendImpl() { | |
| 348 SleepMs(1); | |
| 349 if (HasFatalFailure()) { | |
| 350 // End the test early if a fatal failure (ASSERT_*) has occurred. | |
| 351 test_complete_->Set(); | |
| 352 } | |
| 353 ++send_count_; | |
| 354 InsertAudio(); | |
| 355 if (TestDone()) { | |
| 356 test_complete_->Set(); | |
| 357 } | |
| 358 return true; | |
| 359 } | |
| 360 | |
| 361 static bool CbInsertPacketThread(void* context) { | |
| 362 return reinterpret_cast<AudioCodingModuleMtTest*>(context) | |
| 363 ->CbInsertPacketImpl(); | |
| 364 } | |
| 365 | |
| 366 bool CbInsertPacketImpl() { | |
| 367 SleepMs(1); | |
| 368 { | |
| 369 CriticalSectionScoped lock(crit_sect_.get()); | |
| 370 if (fake_clock_->TimeInMilliseconds() < next_insert_packet_time_ms_) { | |
| 371 return true; | |
| 372 } | |
| 373 next_insert_packet_time_ms_ += 10; | |
| 374 } | |
| 375 // Now we're not holding the crit sect when calling ACM. | |
| 376 ++insert_packet_count_; | |
| 377 InsertPacket(); | |
| 378 return true; | |
| 379 } | |
| 380 | |
| 381 static bool CbPullAudioThread(void* context) { | |
| 382 return reinterpret_cast<AudioCodingModuleMtTest*>(context) | |
| 383 ->CbPullAudioImpl(); | |
| 384 } | |
| 385 | |
| 386 bool CbPullAudioImpl() { | |
| 387 SleepMs(1); | |
| 388 { | |
| 389 CriticalSectionScoped lock(crit_sect_.get()); | |
| 390 // Don't let the insert thread fall behind. | |
| 391 if (next_insert_packet_time_ms_ < fake_clock_->TimeInMilliseconds()) { | |
| 392 return true; | |
| 393 } | |
| 394 ++pull_audio_count_; | |
| 395 } | |
| 396 // Now we're not holding the crit sect when calling ACM. | |
| 397 PullAudio(); | |
| 398 fake_clock_->AdvanceTimeMilliseconds(10); | |
| 399 return true; | |
| 400 } | |
| 401 | |
| 402 rtc::scoped_ptr<ThreadWrapper> send_thread_; | |
| 403 rtc::scoped_ptr<ThreadWrapper> insert_packet_thread_; | |
| 404 rtc::scoped_ptr<ThreadWrapper> pull_audio_thread_; | |
| 405 const rtc::scoped_ptr<EventWrapper> test_complete_; | |
| 406 int send_count_; | |
| 407 int insert_packet_count_; | |
| 408 int pull_audio_count_ GUARDED_BY(crit_sect_); | |
| 409 const rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; | |
| 410 int64_t next_insert_packet_time_ms_ GUARDED_BY(crit_sect_); | |
| 411 rtc::scoped_ptr<SimulatedClock> fake_clock_; | |
| 412 }; | |
| 413 | |
| 414 TEST_F(AudioCodingModuleMtTest, DoTest) { | |
| 415 EXPECT_EQ(kEventSignaled, RunTest()); | |
| 416 } | |
| 417 | |
| 418 // This is a multi-threaded ACM test using iSAC. The test encodes audio | |
| 419 // from a PCM file. The most recent encoded frame is used as input to the | |
| 420 // receiving part. Depending on timing, it may happen that the same RTP packet | |
| 421 // is inserted into the receiver multiple times, but this is a valid use-case, | |
| 422 // and simplifies the test code a lot. | |
| 423 class AcmIsacMtTest : public AudioCodingModuleMtTest { | |
| 424 protected: | |
| 425 static const int kNumPackets = 500; | |
| 426 static const int kNumPullCalls = 500; | |
| 427 | |
| 428 AcmIsacMtTest() | |
| 429 : AudioCodingModuleMtTest(), | |
| 430 last_packet_number_(0) {} | |
| 431 | |
| 432 ~AcmIsacMtTest() {} | |
| 433 | |
| 434 void SetUp() override { | |
| 435 AudioCodingModuleTest::SetUp(); | |
| 436 CreateAcm(); | |
| 437 | |
| 438 // Set up input audio source to read from specified file, loop after 5 | |
| 439 // seconds, and deliver blocks of 10 ms. | |
| 440 const std::string input_file_name = | |
| 441 webrtc::test::ResourcePath("audio_coding/speech_mono_16kHz", "pcm"); | |
| 442 audio_loop_.Init(input_file_name, 5 * kSampleRateHz, kNumSamples10ms); | |
| 443 | |
| 444 // Generate one packet to have something to insert. | |
| 445 int loop_counter = 0; | |
| 446 while (packet_cb_.last_payload_len_bytes() == 0) { | |
| 447 InsertAudio(); | |
| 448 ASSERT_LT(loop_counter++, 10); | |
| 449 } | |
| 450 // Set |last_packet_number_| to one less that |num_calls| so that the packet | |
| 451 // will be fetched in the next InsertPacket() call. | |
| 452 last_packet_number_ = packet_cb_.num_calls() - 1; | |
| 453 | |
| 454 StartThreads(); | |
| 455 } | |
| 456 | |
| 457 void RegisterCodec() override { | |
| 458 static_assert(kSampleRateHz == 16000, "test designed for iSAC 16 kHz"); | |
| 459 | |
| 460 // Register iSAC codec in ACM, effectively unregistering the PCM16B codec | |
| 461 // registered in AudioCodingModuleTest::SetUp(); | |
| 462 ASSERT_TRUE(acm_->RegisterSendCodec(acm2::ACMCodecDB::kISAC, kPayloadType)); | |
| 463 ASSERT_TRUE( | |
| 464 acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kISAC, kPayloadType)); | |
| 465 } | |
| 466 | |
| 467 void InsertPacket() override { | |
| 468 int num_calls = packet_cb_.num_calls(); // Store locally for thread safety. | |
| 469 if (num_calls > last_packet_number_) { | |
| 470 // Get the new payload out from the callback handler. | |
| 471 // Note that since we swap buffers here instead of directly inserting | |
| 472 // a pointer to the data in |packet_cb_|, we avoid locking the callback | |
| 473 // for the duration of the IncomingPacket() call. | |
| 474 packet_cb_.SwapBuffers(&last_payload_vec_); | |
| 475 ASSERT_GT(last_payload_vec_.size(), 0u); | |
| 476 rtp_utility_->Forward(&rtp_header_); | |
| 477 last_packet_number_ = num_calls; | |
| 478 } | |
| 479 ASSERT_GT(last_payload_vec_.size(), 0u); | |
| 480 ASSERT_TRUE(acm_->InsertPacket( | |
| 481 &last_payload_vec_[0], last_payload_vec_.size(), rtp_header_)); | |
| 482 } | |
| 483 | |
| 484 void InsertAudio() override { | |
| 485 memcpy(input_frame_.data_, audio_loop_.GetNextBlock(), kNumSamples10ms); | |
| 486 AudioCodingModuleTest::InsertAudio(); | |
| 487 } | |
| 488 | |
| 489 // This method is the same as AudioCodingModuleMtTest::TestDone(), but here | |
| 490 // it is using the constants defined in this class (i.e., shorter test run). | |
| 491 bool TestDone() override { | |
| 492 if (packet_cb_.num_calls() > kNumPackets) { | |
| 493 CriticalSectionScoped lock(crit_sect_.get()); | |
| 494 if (pull_audio_count_ > kNumPullCalls) { | |
| 495 // Both conditions for completion are met. End the test. | |
| 496 return true; | |
| 497 } | |
| 498 } | |
| 499 return false; | |
| 500 } | |
| 501 | |
| 502 int last_packet_number_; | |
| 503 std::vector<uint8_t> last_payload_vec_; | |
| 504 test::AudioLoop audio_loop_; | |
| 505 }; | |
| 506 | |
| 507 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) | |
| 508 #define IF_ISAC(x) x | |
| 509 #else | |
| 510 #define IF_ISAC(x) DISABLED_##x | |
| 511 #endif | |
| 512 | |
| 513 TEST_F(AcmIsacMtTest, IF_ISAC(DoTest)) { | |
| 514 EXPECT_EQ(kEventSignaled, RunTest()); | |
| 515 } | |
| 516 | |
| 517 // Disabling all of these tests on iOS for now. | |
| 518 // See https://code.google.com/p/webrtc/issues/detail?id=4768 for details. | |
| 519 #if !defined(WEBRTC_IOS) | |
| 520 | |
| 521 class AcmReceiverBitExactness : public ::testing::Test { | |
| 522 public: | |
| 523 static std::string PlatformChecksum(std::string win64, | |
| 524 std::string android, | |
| 525 std::string others) { | |
| 526 #if defined(_WIN32) && defined(WEBRTC_ARCH_64_BITS) | |
| 527 return win64; | |
| 528 #elif defined(WEBRTC_ANDROID) | |
| 529 return android; | |
| 530 #else | |
| 531 return others; | |
| 532 #endif | |
| 533 } | |
| 534 | |
| 535 protected: | |
| 536 void Run(int output_freq_hz, const std::string& checksum_ref) { | |
| 537 const std::string input_file_name = | |
| 538 webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp"); | |
| 539 rtc::scoped_ptr<test::RtpFileSource> packet_source( | |
| 540 test::RtpFileSource::Create(input_file_name)); | |
| 541 #ifdef WEBRTC_ANDROID | |
| 542 // Filter out iLBC and iSAC-swb since they are not supported on Android. | |
| 543 packet_source->FilterOutPayloadType(102); // iLBC. | |
| 544 packet_source->FilterOutPayloadType(104); // iSAC-swb. | |
| 545 #endif | |
| 546 | |
| 547 test::AudioChecksum checksum; | |
| 548 const std::string output_file_name = | |
| 549 webrtc::test::OutputPath() + | |
| 550 ::testing::UnitTest::GetInstance() | |
| 551 ->current_test_info() | |
| 552 ->test_case_name() + | |
| 553 "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name() + | |
| 554 "_output.pcm"; | |
| 555 test::OutputAudioFile output_file(output_file_name); | |
| 556 test::AudioSinkFork output(&checksum, &output_file); | |
| 557 | |
| 558 test::AcmReceiveTest test(packet_source.get(), &output, output_freq_hz, | |
| 559 test::AcmReceiveTest::kArbitraryChannels); | |
| 560 ASSERT_NO_FATAL_FAILURE(test.RegisterNetEqTestCodecs()); | |
| 561 test.Run(); | |
| 562 | |
| 563 std::string checksum_string = checksum.Finish(); | |
| 564 EXPECT_EQ(checksum_ref, checksum_string); | |
| 565 } | |
| 566 }; | |
| 567 | |
| 568 #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISAC)) && \ | |
| 569 defined(WEBRTC_CODEC_ILBC) && defined(WEBRTC_CODEC_G722) | |
| 570 #define IF_ALL_CODECS(x) x | |
| 571 #else | |
| 572 #define IF_ALL_CODECS(x) DISABLED_##x | |
| 573 #endif | |
| 574 | |
| 575 // Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 | |
| 576 #if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) | |
| 577 #define MAYBE_8kHzOutput DISABLED_8kHzOutput | |
| 578 #else | |
| 579 #define MAYBE_8kHzOutput 8kHzOutput | |
| 580 #endif | |
| 581 TEST_F(AcmReceiverBitExactness, IF_ALL_CODECS(MAYBE_8kHzOutput)) { | |
| 582 Run(8000, | |
| 583 PlatformChecksum("dcee98c623b147ebe1b40dd30efa896e", | |
| 584 "adc92e173f908f93b96ba5844209815a", | |
| 585 "908002dc01fc4eb1d2be24eb1d3f354b")); | |
| 586 } | |
| 587 | |
| 588 // Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 | |
| 589 #if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) | |
| 590 #define MAYBE_16kHzOutput DISABLED_16kHzOutput | |
| 591 #else | |
| 592 #define MAYBE_16kHzOutput 16kHzOutput | |
| 593 #endif | |
| 594 TEST_F(AcmReceiverBitExactness, IF_ALL_CODECS(MAYBE_16kHzOutput)) { | |
| 595 Run(16000, | |
| 596 PlatformChecksum("f790e7a8cce4e2c8b7bb5e0e4c5dac0d", | |
| 597 "8cffa6abcb3e18e33b9d857666dff66a", | |
| 598 "a909560b5ca49fa472b17b7b277195e9")); | |
| 599 } | |
| 600 | |
| 601 // Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 | |
| 602 #if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) | |
| 603 #define MAYBE_32kHzOutput DISABLED_32kHzOutput | |
| 604 #else | |
| 605 #define MAYBE_32kHzOutput 32kHzOutput | |
| 606 #endif | |
| 607 TEST_F(AcmReceiverBitExactness, IF_ALL_CODECS(MAYBE_32kHzOutput)) { | |
| 608 Run(32000, | |
| 609 PlatformChecksum("306e0d990ee6e92de3fbecc0123ece37", | |
| 610 "3e126fe894720c3f85edadcc91964ba5", | |
| 611 "441aab4b347fb3db4e9244337aca8d8e")); | |
| 612 } | |
| 613 | |
| 614 // Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 | |
| 615 #if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) | |
| 616 #define MAYBE_48kHzOutput DISABLED_48kHzOutput | |
| 617 #else | |
| 618 #define MAYBE_48kHzOutput 48kHzOutput | |
| 619 #endif | |
| 620 TEST_F(AcmReceiverBitExactness, IF_ALL_CODECS(MAYBE_48kHzOutput)) { | |
| 621 Run(48000, | |
| 622 PlatformChecksum("aa7c232f63a67b2a72703593bdd172e0", | |
| 623 "0155665e93067c4e89256b944dd11999", | |
| 624 "4ee2730fa1daae755e8a8fd3abd779ec")); | |
| 625 } | |
| 626 | |
| 627 // This test verifies bit exactness for the send-side of ACM. The test setup is | |
| 628 // a chain of three different test classes: | |
| 629 // | |
| 630 // test::AcmSendTest -> AcmSenderBitExactness -> test::AcmReceiveTest | |
| 631 // | |
| 632 // The receiver side is driving the test by requesting new packets from | |
| 633 // AcmSenderBitExactness::NextPacket(). This method, in turn, asks for the | |
| 634 // packet from test::AcmSendTest::NextPacket, which inserts audio from the | |
| 635 // input file until one packet is produced. (The input file loops indefinitely.) | |
| 636 // Before passing the packet to the receiver, this test class verifies the | |
| 637 // packet header and updates a payload checksum with the new payload. The | |
| 638 // decoded output from the receiver is also verified with a (separate) checksum. | |
| 639 class AcmSenderBitExactness : public ::testing::Test, | |
| 640 public test::PacketSource { | |
| 641 protected: | |
| 642 static const int kTestDurationMs = 1000; | |
| 643 | |
| 644 AcmSenderBitExactness() | |
| 645 : frame_size_rtp_timestamps_(0), | |
| 646 packet_count_(0), | |
| 647 payload_type_(0), | |
| 648 last_sequence_number_(0), | |
| 649 last_timestamp_(0) {} | |
| 650 | |
| 651 // Sets up the test::AcmSendTest object. Returns true on success, otherwise | |
| 652 // false. | |
| 653 bool SetUpSender() { | |
| 654 const std::string input_file_name = | |
| 655 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); | |
| 656 // Note that |audio_source_| will loop forever. The test duration is set | |
| 657 // explicitly by |kTestDurationMs|. | |
| 658 audio_source_.reset(new test::InputAudioFile(input_file_name)); | |
| 659 static const int kSourceRateHz = 32000; | |
| 660 send_test_.reset(new test::AcmSendTest( | |
| 661 audio_source_.get(), kSourceRateHz, kTestDurationMs)); | |
| 662 return send_test_.get() != NULL; | |
| 663 } | |
| 664 | |
| 665 // Registers a send codec in the test::AcmSendTest object. Returns true on | |
| 666 // success, false on failure. | |
| 667 bool RegisterSendCodec(int codec_type, | |
| 668 int channels, | |
| 669 int payload_type, | |
| 670 int frame_size_samples, | |
| 671 int frame_size_rtp_timestamps) { | |
| 672 payload_type_ = payload_type; | |
| 673 frame_size_rtp_timestamps_ = frame_size_rtp_timestamps; | |
| 674 return send_test_->RegisterCodec( | |
| 675 codec_type, channels, payload_type, frame_size_samples); | |
| 676 } | |
| 677 | |
| 678 // Runs the test. SetUpSender() and RegisterSendCodec() must have been called | |
| 679 // before calling this method. | |
| 680 void Run(const std::string& audio_checksum_ref, | |
| 681 const std::string& payload_checksum_ref, | |
| 682 int expected_packets, | |
| 683 test::AcmReceiveTest::NumOutputChannels expected_channels) { | |
| 684 // Set up the receiver used to decode the packets and verify the decoded | |
| 685 // output. | |
| 686 test::AudioChecksum audio_checksum; | |
| 687 const std::string output_file_name = | |
| 688 webrtc::test::OutputPath() + | |
| 689 ::testing::UnitTest::GetInstance() | |
| 690 ->current_test_info() | |
| 691 ->test_case_name() + | |
| 692 "_" + | |
| 693 ::testing::UnitTest::GetInstance()->current_test_info()->name() + | |
| 694 "_output.pcm"; | |
| 695 test::OutputAudioFile output_file(output_file_name); | |
| 696 // Have the output audio sent both to file and to the checksum calculator. | |
| 697 test::AudioSinkFork output(&audio_checksum, &output_file); | |
| 698 const int kOutputFreqHz = 8000; | |
| 699 test::AcmReceiveTest receive_test( | |
| 700 this, &output, kOutputFreqHz, expected_channels); | |
| 701 ASSERT_NO_FATAL_FAILURE(receive_test.RegisterDefaultCodecs()); | |
| 702 | |
| 703 // This is where the actual test is executed. | |
| 704 receive_test.Run(); | |
| 705 | |
| 706 // Extract and verify the audio checksum. | |
| 707 std::string checksum_string = audio_checksum.Finish(); | |
| 708 EXPECT_EQ(audio_checksum_ref, checksum_string); | |
| 709 | |
| 710 // Extract and verify the payload checksum. | |
| 711 char checksum_result[rtc::Md5Digest::kSize]; | |
| 712 payload_checksum_.Finish(checksum_result, rtc::Md5Digest::kSize); | |
| 713 checksum_string = rtc::hex_encode(checksum_result, rtc::Md5Digest::kSize); | |
| 714 EXPECT_EQ(payload_checksum_ref, checksum_string); | |
| 715 | |
| 716 // Verify number of packets produced. | |
| 717 EXPECT_EQ(expected_packets, packet_count_); | |
| 718 } | |
| 719 | |
| 720 // Returns a pointer to the next packet. Returns NULL if the source is | |
| 721 // depleted (i.e., the test duration is exceeded), or if an error occurred. | |
| 722 // Inherited from test::PacketSource. | |
| 723 test::Packet* NextPacket() override { | |
| 724 // Get the next packet from AcmSendTest. Ownership of |packet| is | |
| 725 // transferred to this method. | |
| 726 test::Packet* packet = send_test_->NextPacket(); | |
| 727 if (!packet) | |
| 728 return NULL; | |
| 729 | |
| 730 VerifyPacket(packet); | |
| 731 // TODO(henrik.lundin) Save the packet to file as well. | |
| 732 | |
| 733 // Pass it on to the caller. The caller becomes the owner of |packet|. | |
| 734 return packet; | |
| 735 } | |
| 736 | |
| 737 // Verifies the packet. | |
| 738 void VerifyPacket(const test::Packet* packet) { | |
| 739 EXPECT_TRUE(packet->valid_header()); | |
| 740 // (We can check the header fields even if valid_header() is false.) | |
| 741 EXPECT_EQ(payload_type_, packet->header().payloadType); | |
| 742 if (packet_count_ > 0) { | |
| 743 // This is not the first packet. | |
| 744 uint16_t sequence_number_diff = | |
| 745 packet->header().sequenceNumber - last_sequence_number_; | |
| 746 EXPECT_EQ(1, sequence_number_diff); | |
| 747 uint32_t timestamp_diff = packet->header().timestamp - last_timestamp_; | |
| 748 EXPECT_EQ(frame_size_rtp_timestamps_, timestamp_diff); | |
| 749 } | |
| 750 ++packet_count_; | |
| 751 last_sequence_number_ = packet->header().sequenceNumber; | |
| 752 last_timestamp_ = packet->header().timestamp; | |
| 753 // Update the checksum. | |
| 754 payload_checksum_.Update(packet->payload(), packet->payload_length_bytes()); | |
| 755 } | |
| 756 | |
| 757 void SetUpTest(int codec_type, | |
| 758 int channels, | |
| 759 int payload_type, | |
| 760 int codec_frame_size_samples, | |
| 761 int codec_frame_size_rtp_timestamps) { | |
| 762 ASSERT_TRUE(SetUpSender()); | |
| 763 ASSERT_TRUE(RegisterSendCodec(codec_type, | |
| 764 channels, | |
| 765 payload_type, | |
| 766 codec_frame_size_samples, | |
| 767 codec_frame_size_rtp_timestamps)); | |
| 768 } | |
| 769 | |
| 770 rtc::scoped_ptr<test::AcmSendTest> send_test_; | |
| 771 rtc::scoped_ptr<test::InputAudioFile> audio_source_; | |
| 772 uint32_t frame_size_rtp_timestamps_; | |
| 773 int packet_count_; | |
| 774 uint8_t payload_type_; | |
| 775 uint16_t last_sequence_number_; | |
| 776 uint32_t last_timestamp_; | |
| 777 rtc::Md5Digest payload_checksum_; | |
| 778 }; | |
| 779 | |
| 780 // Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 | |
| 781 #if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) | |
| 782 #define MAYBE_IsacWb30ms DISABLED_IsacWb30ms | |
| 783 #else | |
| 784 #define MAYBE_IsacWb30ms IsacWb30ms | |
| 785 #endif | |
| 786 TEST_F(AcmSenderBitExactness, IF_ISAC(MAYBE_IsacWb30ms)) { | |
| 787 ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kISAC, 1, 103, 480, 480)); | |
| 788 Run(AcmReceiverBitExactness::PlatformChecksum( | |
| 789 "c7e5bdadfa2871df95639fcc297cf23d", | |
| 790 "0499ca260390769b3172136faad925b9", | |
| 791 "0b58f9eeee43d5891f5f6c75e77984a3"), | |
| 792 AcmReceiverBitExactness::PlatformChecksum( | |
| 793 "d42cb5195463da26c8129bbfe73a22e6", | |
| 794 "83de248aea9c3c2bd680b6952401b4ca", | |
| 795 "3c79f16f34218271f3dca4e2b1dfe1bb"), | |
| 796 33, | |
| 797 test::AcmReceiveTest::kMonoOutput); | |
| 798 } | |
| 799 | |
| 800 // Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 | |
| 801 #if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) | |
| 802 #define MAYBE_IsacWb60ms DISABLED_IsacWb60ms | |
| 803 #else | |
| 804 #define MAYBE_IsacWb60ms IsacWb60ms | |
| 805 #endif | |
| 806 TEST_F(AcmSenderBitExactness, IF_ISAC(MAYBE_IsacWb60ms)) { | |
| 807 ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kISAC, 1, 103, 960, 960)); | |
| 808 Run(AcmReceiverBitExactness::PlatformChecksum( | |
| 809 "14d63c5f08127d280e722e3191b73bdd", | |
| 810 "8da003e16c5371af2dc2be79a50f9076", | |
| 811 "1ad29139a04782a33daad8c2b9b35875"), | |
| 812 AcmReceiverBitExactness::PlatformChecksum( | |
| 813 "ebe04a819d3a9d83a83a17f271e1139a", | |
| 814 "97aeef98553b5a4b5a68f8b716e8eaf0", | |
| 815 "9e0a0ab743ad987b55b8e14802769c56"), | |
| 816 16, | |
| 817 test::AcmReceiveTest::kMonoOutput); | |
| 818 } | |
| 819 | |
| 820 #ifdef WEBRTC_CODEC_ISAC | |
| 821 #define IF_ISAC_FLOAT(x) x | |
| 822 #else | |
| 823 #define IF_ISAC_FLOAT(x) DISABLED_##x | |
| 824 #endif | |
| 825 | |
| 826 TEST_F(AcmSenderBitExactness, DISABLED_ON_ANDROID(IF_ISAC_FLOAT(IsacSwb30ms))) { | |
| 827 ASSERT_NO_FATAL_FAILURE( | |
| 828 SetUpTest(acm2::ACMCodecDB::kISACSWB, 1, 104, 960, 960)); | |
| 829 Run(AcmReceiverBitExactness::PlatformChecksum( | |
| 830 "2b3c387d06f00b7b7aad4c9be56fb83d", | |
| 831 "", | |
| 832 "5683b58da0fbf2063c7adc2e6bfb3fb8"), | |
| 833 AcmReceiverBitExactness::PlatformChecksum( | |
| 834 "bcc2041e7744c7ebd9f701866856849c", | |
| 835 "", | |
| 836 "ce86106a93419aefb063097108ec94ab"), | |
| 837 33, test::AcmReceiveTest::kMonoOutput); | |
| 838 } | |
| 839 | |
| 840 TEST_F(AcmSenderBitExactness, Pcm16_8000khz_10ms) { | |
| 841 ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kPCM16B, 1, 107, 80, 80)); | |
| 842 Run("de4a98e1406f8b798d99cd0704e862e2", | |
| 843 "c1edd36339ce0326cc4550041ad719a0", | |
| 844 100, | |
| 845 test::AcmReceiveTest::kMonoOutput); | |
| 846 } | |
| 847 | |
| 848 TEST_F(AcmSenderBitExactness, Pcm16_16000khz_10ms) { | |
| 849 ASSERT_NO_FATAL_FAILURE( | |
| 850 SetUpTest(acm2::ACMCodecDB::kPCM16Bwb, 1, 108, 160, 160)); | |
| 851 Run("ae646d7b68384a1269cc080dd4501916", | |
| 852 "ad786526383178b08d80d6eee06e9bad", | |
| 853 100, | |
| 854 test::AcmReceiveTest::kMonoOutput); | |
| 855 } | |
| 856 | |
| 857 TEST_F(AcmSenderBitExactness, Pcm16_32000khz_10ms) { | |
| 858 ASSERT_NO_FATAL_FAILURE( | |
| 859 SetUpTest(acm2::ACMCodecDB::kPCM16Bswb32kHz, 1, 109, 320, 320)); | |
| 860 Run("7fe325e8fbaf755e3c5df0b11a4774fb", | |
| 861 "5ef82ea885e922263606c6fdbc49f651", | |
| 862 100, | |
| 863 test::AcmReceiveTest::kMonoOutput); | |
| 864 } | |
| 865 | |
| 866 TEST_F(AcmSenderBitExactness, Pcm16_stereo_8000khz_10ms) { | |
| 867 ASSERT_NO_FATAL_FAILURE( | |
| 868 SetUpTest(acm2::ACMCodecDB::kPCM16B_2ch, 2, 111, 80, 80)); | |
| 869 Run("fb263b74e7ac3de915474d77e4744ceb", | |
| 870 "62ce5adb0d4965d0a52ec98ae7f98974", | |
| 871 100, | |
| 872 test::AcmReceiveTest::kStereoOutput); | |
| 873 } | |
| 874 | |
| 875 TEST_F(AcmSenderBitExactness, Pcm16_stereo_16000khz_10ms) { | |
| 876 ASSERT_NO_FATAL_FAILURE( | |
| 877 SetUpTest(acm2::ACMCodecDB::kPCM16Bwb_2ch, 2, 112, 160, 160)); | |
| 878 Run("d09e9239553649d7ac93e19d304281fd", | |
| 879 "41ca8edac4b8c71cd54fd9f25ec14870", | |
| 880 100, | |
| 881 test::AcmReceiveTest::kStereoOutput); | |
| 882 } | |
| 883 | |
| 884 TEST_F(AcmSenderBitExactness, Pcm16_stereo_32000khz_10ms) { | |
| 885 ASSERT_NO_FATAL_FAILURE( | |
| 886 SetUpTest(acm2::ACMCodecDB::kPCM16Bswb32kHz_2ch, 2, 113, 320, 320)); | |
| 887 Run("5f025d4f390982cc26b3d92fe02e3044", | |
| 888 "50e58502fb04421bf5b857dda4c96879", | |
| 889 100, | |
| 890 test::AcmReceiveTest::kStereoOutput); | |
| 891 } | |
| 892 | |
| 893 TEST_F(AcmSenderBitExactness, Pcmu_20ms) { | |
| 894 ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kPCMU, 1, 0, 160, 160)); | |
| 895 Run("81a9d4c0bb72e9becc43aef124c981e9", | |
| 896 "8f9b8750bd80fe26b6cbf6659b89f0f9", | |
| 897 50, | |
| 898 test::AcmReceiveTest::kMonoOutput); | |
| 899 } | |
| 900 | |
| 901 TEST_F(AcmSenderBitExactness, Pcma_20ms) { | |
| 902 ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kPCMA, 1, 8, 160, 160)); | |
| 903 Run("39611f798969053925a49dc06d08de29", | |
| 904 "6ad745e55aa48981bfc790d0eeef2dd1", | |
| 905 50, | |
| 906 test::AcmReceiveTest::kMonoOutput); | |
| 907 } | |
| 908 | |
| 909 TEST_F(AcmSenderBitExactness, Pcmu_stereo_20ms) { | |
| 910 ASSERT_NO_FATAL_FAILURE( | |
| 911 SetUpTest(acm2::ACMCodecDB::kPCMU_2ch, 2, 110, 160, 160)); | |
| 912 Run("437bec032fdc5cbaa0d5175430af7b18", | |
| 913 "60b6f25e8d1e74cb679cfe756dd9bca5", | |
| 914 50, | |
| 915 test::AcmReceiveTest::kStereoOutput); | |
| 916 } | |
| 917 | |
| 918 TEST_F(AcmSenderBitExactness, Pcma_stereo_20ms) { | |
| 919 ASSERT_NO_FATAL_FAILURE( | |
| 920 SetUpTest(acm2::ACMCodecDB::kPCMA_2ch, 2, 118, 160, 160)); | |
| 921 Run("a5c6d83c5b7cedbeff734238220a4b0c", | |
| 922 "92b282c83efd20e7eeef52ba40842cf7", | |
| 923 50, | |
| 924 test::AcmReceiveTest::kStereoOutput); | |
| 925 } | |
| 926 | |
| 927 #ifdef WEBRTC_CODEC_ILBC | |
| 928 #define IF_ILBC(x) x | |
| 929 #else | |
| 930 #define IF_ILBC(x) DISABLED_##x | |
| 931 #endif | |
| 932 | |
| 933 TEST_F(AcmSenderBitExactness, DISABLED_ON_ANDROID(IF_ILBC(Ilbc_30ms))) { | |
| 934 ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kILBC, 1, 102, 240, 240)); | |
| 935 Run(AcmReceiverBitExactness::PlatformChecksum( | |
| 936 "7b6ec10910debd9af08011d3ed5249f7", | |
| 937 "android_audio", | |
| 938 "7b6ec10910debd9af08011d3ed5249f7"), | |
| 939 AcmReceiverBitExactness::PlatformChecksum( | |
| 940 "cfae2e9f6aba96e145f2bcdd5050ce78", | |
| 941 "android_payload", | |
| 942 "cfae2e9f6aba96e145f2bcdd5050ce78"), | |
| 943 33, | |
| 944 test::AcmReceiveTest::kMonoOutput); | |
| 945 } | |
| 946 | |
| 947 #ifdef WEBRTC_CODEC_G722 | |
| 948 #define IF_G722(x) x | |
| 949 #else | |
| 950 #define IF_G722(x) DISABLED_##x | |
| 951 #endif | |
| 952 | |
| 953 TEST_F(AcmSenderBitExactness, DISABLED_ON_ANDROID(IF_G722(G722_20ms))) { | |
| 954 ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kG722, 1, 9, 320, 160)); | |
| 955 Run(AcmReceiverBitExactness::PlatformChecksum( | |
| 956 "7d759436f2533582950d148b5161a36c", | |
| 957 "android_audio", | |
| 958 "7d759436f2533582950d148b5161a36c"), | |
| 959 AcmReceiverBitExactness::PlatformChecksum( | |
| 960 "fc68a87e1380614e658087cb35d5ca10", | |
| 961 "android_payload", | |
| 962 "fc68a87e1380614e658087cb35d5ca10"), | |
| 963 50, | |
| 964 test::AcmReceiveTest::kMonoOutput); | |
| 965 } | |
| 966 | |
| 967 TEST_F(AcmSenderBitExactness, DISABLED_ON_ANDROID(IF_G722(G722_stereo_20ms))) { | |
| 968 ASSERT_NO_FATAL_FAILURE( | |
| 969 SetUpTest(acm2::ACMCodecDB::kG722_2ch, 2, 119, 320, 160)); | |
| 970 Run(AcmReceiverBitExactness::PlatformChecksum( | |
| 971 "7190ee718ab3d80eca181e5f7140c210", | |
| 972 "android_audio", | |
| 973 "7190ee718ab3d80eca181e5f7140c210"), | |
| 974 AcmReceiverBitExactness::PlatformChecksum( | |
| 975 "66516152eeaa1e650ad94ff85f668dac", | |
| 976 "android_payload", | |
| 977 "66516152eeaa1e650ad94ff85f668dac"), | |
| 978 50, | |
| 979 test::AcmReceiveTest::kStereoOutput); | |
| 980 } | |
| 981 | |
| 982 // Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 | |
| 983 #if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) | |
| 984 #define MAYBE_Opus_stereo_20ms DISABLED_Opus_stereo_20ms | |
| 985 #else | |
| 986 #define MAYBE_Opus_stereo_20ms Opus_stereo_20ms | |
| 987 #endif | |
| 988 TEST_F(AcmSenderBitExactness, MAYBE_Opus_stereo_20ms) { | |
| 989 ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kOpus, 2, 120, 960, 960)); | |
| 990 Run(AcmReceiverBitExactness::PlatformChecksum( | |
| 991 "855041f2490b887302bce9d544731849", | |
| 992 "1e1a0fce893fef2d66886a7f09e2ebce", | |
| 993 "855041f2490b887302bce9d544731849"), | |
| 994 AcmReceiverBitExactness::PlatformChecksum( | |
| 995 "d781cce1ab986b618d0da87226cdde30", | |
| 996 "1a1fe04dd12e755949987c8d729fb3e0", | |
| 997 "d781cce1ab986b618d0da87226cdde30"), | |
| 998 50, | |
| 999 test::AcmReceiveTest::kStereoOutput); | |
| 1000 } | |
| 1001 | |
| 1002 #endif | |
| 1003 | |
| 1004 } // namespace webrtc | |
| OLD | NEW |