xref: /aosp_15_r20/external/webrtc/modules/audio_coding/test/target_delay_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 <memory>
12 
13 #include "api/audio/audio_frame.h"
14 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
15 #include "api/rtp_headers.h"
16 #include "modules/audio_coding/acm2/acm_receiver.h"
17 #include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
18 #include "modules/audio_coding/include/audio_coding_module.h"
19 #include "test/gtest.h"
20 #include "test/testsupport/file_utils.h"
21 
22 namespace webrtc {
23 
24 class TargetDelayTest : public ::testing::Test {
25  protected:
TargetDelayTest()26   TargetDelayTest()
27       : receiver_(
28             AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory())) {}
29 
~TargetDelayTest()30   ~TargetDelayTest() {}
31 
SetUp()32   void SetUp() {
33     constexpr int pltype = 108;
34     std::map<int, SdpAudioFormat> receive_codecs = {
35         {pltype, {"L16", kSampleRateHz, 1}}};
36     receiver_.SetCodecs(receive_codecs);
37 
38     rtp_header_.payloadType = pltype;
39     rtp_header_.timestamp = 0;
40     rtp_header_.ssrc = 0x12345678;
41     rtp_header_.markerBit = false;
42     rtp_header_.sequenceNumber = 0;
43 
44     int16_t audio[kFrameSizeSamples];
45     const int kRange = 0x7FF;  // 2047, easy for masking.
46     for (size_t n = 0; n < kFrameSizeSamples; ++n)
47       audio[n] = (rand() & kRange) - kRange / 2;
48     WebRtcPcm16b_Encode(audio, kFrameSizeSamples, payload_);
49   }
50 
OutOfRangeInput()51   void OutOfRangeInput() {
52     EXPECT_EQ(-1, SetMinimumDelay(-1));
53     EXPECT_EQ(-1, SetMinimumDelay(10001));
54   }
55 
TargetDelayBufferMinMax()56   void TargetDelayBufferMinMax() {
57     const int kTargetMinDelayMs = kNum10msPerFrame * 10;
58     ASSERT_EQ(0, SetMinimumDelay(kTargetMinDelayMs));
59     for (int m = 0; m < 30; ++m)  // Run enough iterations to fill the buffer.
60       Run(true);
61     int clean_optimal_delay = GetCurrentOptimalDelayMs();
62     EXPECT_EQ(kTargetMinDelayMs, clean_optimal_delay);
63 
64     const int kTargetMaxDelayMs = 2 * (kNum10msPerFrame * 10);
65     ASSERT_EQ(0, SetMaximumDelay(kTargetMaxDelayMs));
66     for (int n = 0; n < 30; ++n)  // Run enough iterations to fill the buffer.
67       Run(false);
68 
69     int capped_optimal_delay = GetCurrentOptimalDelayMs();
70     EXPECT_EQ(kTargetMaxDelayMs, capped_optimal_delay);
71   }
72 
73  private:
74   static const int kSampleRateHz = 16000;
75   static const int kNum10msPerFrame = 2;
76   static const size_t kFrameSizeSamples = 320;  // 20 ms @ 16 kHz.
77   // payload-len = frame-samples * 2 bytes/sample.
78   static const int kPayloadLenBytes = 320 * 2;
79   // Inter-arrival time in number of packets in a jittery channel. One is no
80   // jitter.
81   static const int kInterarrivalJitterPacket = 2;
82 
Push()83   void Push() {
84     rtp_header_.timestamp += kFrameSizeSamples;
85     rtp_header_.sequenceNumber++;
86     ASSERT_EQ(0, receiver_.InsertPacket(rtp_header_,
87                                         rtc::ArrayView<const uint8_t>(
88                                             payload_, kFrameSizeSamples * 2)));
89   }
90 
91   // Pull audio equivalent to the amount of audio in one RTP packet.
Pull()92   void Pull() {
93     AudioFrame frame;
94     bool muted;
95     for (int k = 0; k < kNum10msPerFrame; ++k) {  // Pull one frame.
96       ASSERT_EQ(0, receiver_.GetAudio(-1, &frame, &muted));
97       ASSERT_FALSE(muted);
98       // Had to use ASSERT_TRUE, ASSERT_EQ generated error.
99       ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_);
100       ASSERT_EQ(1u, frame.num_channels_);
101       ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_);
102     }
103   }
104 
Run(bool clean)105   void Run(bool clean) {
106     for (int n = 0; n < 10; ++n) {
107       for (int m = 0; m < 5; ++m) {
108         Push();
109         Pull();
110       }
111 
112       if (!clean) {
113         for (int m = 0; m < 10; ++m) {  // Long enough to trigger delay change.
114           Push();
115           for (int n = 0; n < kInterarrivalJitterPacket; ++n)
116             Pull();
117         }
118       }
119     }
120   }
121 
SetMinimumDelay(int delay_ms)122   int SetMinimumDelay(int delay_ms) {
123     return receiver_.SetMinimumDelay(delay_ms);
124   }
125 
SetMaximumDelay(int delay_ms)126   int SetMaximumDelay(int delay_ms) {
127     return receiver_.SetMaximumDelay(delay_ms);
128   }
129 
GetCurrentOptimalDelayMs()130   int GetCurrentOptimalDelayMs() {
131     NetworkStatistics stats;
132     receiver_.GetNetworkStatistics(&stats);
133     return stats.preferredBufferSize;
134   }
135 
136   acm2::AcmReceiver receiver_;
137   RTPHeader rtp_header_;
138   uint8_t payload_[kPayloadLenBytes];
139 };
140 
141 // Flaky on iOS: webrtc:7057.
142 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
143 #define MAYBE_OutOfRangeInput DISABLED_OutOfRangeInput
144 #else
145 #define MAYBE_OutOfRangeInput OutOfRangeInput
146 #endif
TEST_F(TargetDelayTest,MAYBE_OutOfRangeInput)147 TEST_F(TargetDelayTest, MAYBE_OutOfRangeInput) {
148   OutOfRangeInput();
149 }
150 
151 // Flaky on iOS: webrtc:7057.
152 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
153 #define MAYBE_TargetDelayBufferMinMax DISABLED_TargetDelayBufferMinMax
154 #else
155 #define MAYBE_TargetDelayBufferMinMax TargetDelayBufferMinMax
156 #endif
TEST_F(TargetDelayTest,MAYBE_TargetDelayBufferMinMax)157 TEST_F(TargetDelayTest, MAYBE_TargetDelayBufferMinMax) {
158   TargetDelayBufferMinMax();
159 }
160 
161 }  // namespace webrtc
162