| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2013 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 "testing/gtest/include/gtest/gtest.h" | |
| 12 #include "webrtc/base/scoped_ptr.h" | |
| 13 #include "webrtc/common_types.h" | |
| 14 #include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" | |
| 15 #include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" | |
| 16 #include "webrtc/modules/audio_coding/main/test/utility.h" | |
| 17 #include "webrtc/modules/include/module_common_types.h" | |
| 18 #include "webrtc/system_wrappers/include/sleep.h" | |
| 19 #include "webrtc/test/testsupport/fileutils.h" | |
| 20 #include "webrtc/test/testsupport/gtest_disable.h" | |
| 21 | |
| 22 namespace webrtc { | |
| 23 | |
| 24 class TargetDelayTest : public ::testing::Test { | |
| 25 protected: | |
| 26 TargetDelayTest() : acm_(AudioCodingModule::Create(0)) {} | |
| 27 | |
| 28 ~TargetDelayTest() {} | |
| 29 | |
| 30 void SetUp() { | |
| 31 EXPECT_TRUE(acm_.get() != NULL); | |
| 32 | |
| 33 CodecInst codec; | |
| 34 ASSERT_EQ(0, AudioCodingModule::Codec("L16", &codec, kSampleRateHz, 1)); | |
| 35 ASSERT_EQ(0, acm_->InitializeReceiver()); | |
| 36 ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec)); | |
| 37 | |
| 38 rtp_info_.header.payloadType = codec.pltype; | |
| 39 rtp_info_.header.timestamp = 0; | |
| 40 rtp_info_.header.ssrc = 0x12345678; | |
| 41 rtp_info_.header.markerBit = false; | |
| 42 rtp_info_.header.sequenceNumber = 0; | |
| 43 rtp_info_.type.Audio.channel = 1; | |
| 44 rtp_info_.type.Audio.isCNG = false; | |
| 45 rtp_info_.frameType = kAudioFrameSpeech; | |
| 46 | |
| 47 int16_t audio[kFrameSizeSamples]; | |
| 48 const int kRange = 0x7FF; // 2047, easy for masking. | |
| 49 for (size_t n = 0; n < kFrameSizeSamples; ++n) | |
| 50 audio[n] = (rand() & kRange) - kRange / 2; | |
| 51 WebRtcPcm16b_Encode(audio, kFrameSizeSamples, payload_); | |
| 52 } | |
| 53 | |
| 54 void OutOfRangeInput() { | |
| 55 EXPECT_EQ(-1, SetMinimumDelay(-1)); | |
| 56 EXPECT_EQ(-1, SetMinimumDelay(10001)); | |
| 57 } | |
| 58 | |
| 59 void NoTargetDelayBufferSizeChanges() { | |
| 60 for (int n = 0; n < 30; ++n) // Run enough iterations. | |
| 61 Run(true); | |
| 62 int clean_optimal_delay = GetCurrentOptimalDelayMs(); | |
| 63 Run(false); // Run with jitter. | |
| 64 int jittery_optimal_delay = GetCurrentOptimalDelayMs(); | |
| 65 EXPECT_GT(jittery_optimal_delay, clean_optimal_delay); | |
| 66 int required_delay = RequiredDelay(); | |
| 67 EXPECT_GT(required_delay, 0); | |
| 68 EXPECT_NEAR(required_delay, jittery_optimal_delay, 1); | |
| 69 } | |
| 70 | |
| 71 void WithTargetDelayBufferNotChanging() { | |
| 72 // A target delay that is one packet larger than jitter. | |
| 73 const int kTargetDelayMs = (kInterarrivalJitterPacket + 1) * | |
| 74 kNum10msPerFrame * 10; | |
| 75 ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs)); | |
| 76 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer. | |
| 77 Run(true); | |
| 78 int clean_optimal_delay = GetCurrentOptimalDelayMs(); | |
| 79 EXPECT_EQ(kTargetDelayMs, clean_optimal_delay); | |
| 80 Run(false); // Run with jitter. | |
| 81 int jittery_optimal_delay = GetCurrentOptimalDelayMs(); | |
| 82 EXPECT_EQ(jittery_optimal_delay, clean_optimal_delay); | |
| 83 } | |
| 84 | |
| 85 void RequiredDelayAtCorrectRange() { | |
| 86 for (int n = 0; n < 30; ++n) // Run clean and store delay. | |
| 87 Run(true); | |
| 88 int clean_optimal_delay = GetCurrentOptimalDelayMs(); | |
| 89 | |
| 90 // A relatively large delay. | |
| 91 const int kTargetDelayMs = (kInterarrivalJitterPacket + 10) * | |
| 92 kNum10msPerFrame * 10; | |
| 93 ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs)); | |
| 94 for (int n = 0; n < 300; ++n) // Run enough iterations to fill the buffer. | |
| 95 Run(true); | |
| 96 Run(false); // Run with jitter. | |
| 97 | |
| 98 int jittery_optimal_delay = GetCurrentOptimalDelayMs(); | |
| 99 EXPECT_EQ(kTargetDelayMs, jittery_optimal_delay); | |
| 100 | |
| 101 int required_delay = RequiredDelay(); | |
| 102 | |
| 103 // Checking |required_delay| is in correct range. | |
| 104 EXPECT_GT(required_delay, 0); | |
| 105 EXPECT_GT(jittery_optimal_delay, required_delay); | |
| 106 EXPECT_GT(required_delay, clean_optimal_delay); | |
| 107 | |
| 108 // A tighter check for the value of |required_delay|. | |
| 109 // The jitter forces a delay of | |
| 110 // |kInterarrivalJitterPacket * kNum10msPerFrame * 10| milliseconds. So we | |
| 111 // expect |required_delay| be close to that. | |
| 112 EXPECT_NEAR(kInterarrivalJitterPacket * kNum10msPerFrame * 10, | |
| 113 required_delay, 1); | |
| 114 } | |
| 115 | |
| 116 void TargetDelayBufferMinMax() { | |
| 117 const int kTargetMinDelayMs = kNum10msPerFrame * 10; | |
| 118 ASSERT_EQ(0, SetMinimumDelay(kTargetMinDelayMs)); | |
| 119 for (int m = 0; m < 30; ++m) // Run enough iterations to fill the buffer. | |
| 120 Run(true); | |
| 121 int clean_optimal_delay = GetCurrentOptimalDelayMs(); | |
| 122 EXPECT_EQ(kTargetMinDelayMs, clean_optimal_delay); | |
| 123 | |
| 124 const int kTargetMaxDelayMs = 2 * (kNum10msPerFrame * 10); | |
| 125 ASSERT_EQ(0, SetMaximumDelay(kTargetMaxDelayMs)); | |
| 126 for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer. | |
| 127 Run(false); | |
| 128 | |
| 129 int capped_optimal_delay = GetCurrentOptimalDelayMs(); | |
| 130 EXPECT_EQ(kTargetMaxDelayMs, capped_optimal_delay); | |
| 131 } | |
| 132 | |
| 133 private: | |
| 134 static const int kSampleRateHz = 16000; | |
| 135 static const int kNum10msPerFrame = 2; | |
| 136 static const size_t kFrameSizeSamples = 320; // 20 ms @ 16 kHz. | |
| 137 // payload-len = frame-samples * 2 bytes/sample. | |
| 138 static const int kPayloadLenBytes = 320 * 2; | |
| 139 // Inter-arrival time in number of packets in a jittery channel. One is no | |
| 140 // jitter. | |
| 141 static const int kInterarrivalJitterPacket = 2; | |
| 142 | |
| 143 void Push() { | |
| 144 rtp_info_.header.timestamp += kFrameSizeSamples; | |
| 145 rtp_info_.header.sequenceNumber++; | |
| 146 ASSERT_EQ(0, acm_->IncomingPacket(payload_, kFrameSizeSamples * 2, | |
| 147 rtp_info_)); | |
| 148 } | |
| 149 | |
| 150 // Pull audio equivalent to the amount of audio in one RTP packet. | |
| 151 void Pull() { | |
| 152 AudioFrame frame; | |
| 153 for (int k = 0; k < kNum10msPerFrame; ++k) { // Pull one frame. | |
| 154 ASSERT_EQ(0, acm_->PlayoutData10Ms(-1, &frame)); | |
| 155 // Had to use ASSERT_TRUE, ASSERT_EQ generated error. | |
| 156 ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_); | |
| 157 ASSERT_EQ(1, frame.num_channels_); | |
| 158 ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_); | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 void Run(bool clean) { | |
| 163 for (int n = 0; n < 10; ++n) { | |
| 164 for (int m = 0; m < 5; ++m) { | |
| 165 Push(); | |
| 166 Pull(); | |
| 167 } | |
| 168 | |
| 169 if (!clean) { | |
| 170 for (int m = 0; m < 10; ++m) { // Long enough to trigger delay change. | |
| 171 Push(); | |
| 172 for (int n = 0; n < kInterarrivalJitterPacket; ++n) | |
| 173 Pull(); | |
| 174 } | |
| 175 } | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 int SetMinimumDelay(int delay_ms) { | |
| 180 return acm_->SetMinimumPlayoutDelay(delay_ms); | |
| 181 } | |
| 182 | |
| 183 int SetMaximumDelay(int delay_ms) { | |
| 184 return acm_->SetMaximumPlayoutDelay(delay_ms); | |
| 185 } | |
| 186 | |
| 187 int GetCurrentOptimalDelayMs() { | |
| 188 NetworkStatistics stats; | |
| 189 acm_->GetNetworkStatistics(&stats); | |
| 190 return stats.preferredBufferSize; | |
| 191 } | |
| 192 | |
| 193 int RequiredDelay() { | |
| 194 return acm_->LeastRequiredDelayMs(); | |
| 195 } | |
| 196 | |
| 197 rtc::scoped_ptr<AudioCodingModule> acm_; | |
| 198 WebRtcRTPHeader rtp_info_; | |
| 199 uint8_t payload_[kPayloadLenBytes]; | |
| 200 }; | |
| 201 | |
| 202 TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(OutOfRangeInput)) { | |
| 203 OutOfRangeInput(); | |
| 204 } | |
| 205 | |
| 206 TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(NoTargetDelayBufferSizeChanges)) { | |
| 207 NoTargetDelayBufferSizeChanges(); | |
| 208 } | |
| 209 | |
| 210 TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(WithTargetDelayBufferNotChanging)) { | |
| 211 WithTargetDelayBufferNotChanging(); | |
| 212 } | |
| 213 | |
| 214 TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(RequiredDelayAtCorrectRange)) { | |
| 215 RequiredDelayAtCorrectRange(); | |
| 216 } | |
| 217 | |
| 218 TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(TargetDelayBufferMinMax)) { | |
| 219 TargetDelayBufferMinMax(); | |
| 220 } | |
| 221 | |
| 222 } // namespace webrtc | |
| 223 | |
| OLD | NEW |