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/common_types.h" 13#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" 14#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" 15#include "webrtc/modules/audio_coding/main/test/utility.h" 16#include "webrtc/modules/interface/module_common_types.h" 17#include "webrtc/system_wrappers/interface/scoped_ptr.h" 18#include "webrtc/system_wrappers/interface/sleep.h" 19#include "webrtc/test/testsupport/fileutils.h" 20#include "webrtc/test/testsupport/gtest_disable.h" 21 22namespace webrtc { 23 24class 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 (int 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 int 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 ACMNetworkStatistics stats; 189 acm_->NetworkStatistics(&stats); 190 return stats.preferredBufferSize; 191 } 192 193 int RequiredDelay() { 194 return acm_->LeastRequiredDelayMs(); 195 } 196 197 scoped_ptr<AudioCodingModule> acm_; 198 WebRtcRTPHeader rtp_info_; 199 uint8_t payload_[kPayloadLenBytes]; 200}; 201 202TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(OutOfRangeInput)) { 203 OutOfRangeInput(); 204} 205 206TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(NoTargetDelayBufferSizeChanges)) { 207 NoTargetDelayBufferSizeChanges(); 208} 209 210TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(WithTargetDelayBufferNotChanging)) { 211 WithTargetDelayBufferNotChanging(); 212} 213 214TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(RequiredDelayAtCorrectRange)) { 215 RequiredDelayAtCorrectRange(); 216} 217 218TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(TargetDelayBufferMinMax)) { 219 TargetDelayBufferMinMax(); 220} 221 222} // namespace webrtc 223 224