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