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