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 "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 
     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 (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 
    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 
    224