1 /*
2 * Copyright (c) 2016 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 "modules/audio_coding/audio_network_adaptor/event_log_writer.h"
12
13 #include <memory>
14
15 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
16 #include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
17 #include "rtc_base/checks.h"
18 #include "test/gtest.h"
19
20 namespace webrtc {
21
22 namespace {
23
24 constexpr int kMinBitrateChangeBps = 5000;
25 constexpr float kMinPacketLossChangeFraction = 0.5;
26 constexpr float kMinBitrateChangeFraction = 0.25;
27
28 constexpr int kHighBitrateBps = 70000;
29 constexpr int kLowBitrateBps = 10000;
30 constexpr int kFrameLengthMs = 60;
31 constexpr bool kEnableFec = true;
32 constexpr bool kEnableDtx = true;
33 constexpr float kPacketLossFraction = 0.05f;
34 constexpr size_t kNumChannels = 1;
35
36 MATCHER_P(IsRtcEventAnaConfigEqualTo, config, "") {
37 if (arg->GetType() != RtcEvent::Type::AudioNetworkAdaptation) {
38 return false;
39 }
40 auto ana_event = static_cast<RtcEventAudioNetworkAdaptation*>(arg);
41 return ana_event->config() == config;
42 }
43
44 struct EventLogWriterStates {
45 std::unique_ptr<EventLogWriter> event_log_writer;
46 std::unique_ptr<testing::StrictMock<MockRtcEventLog>> event_log;
47 AudioEncoderRuntimeConfig runtime_config;
48 };
49
CreateEventLogWriter()50 EventLogWriterStates CreateEventLogWriter() {
51 EventLogWriterStates state;
52 state.event_log.reset(new ::testing::StrictMock<MockRtcEventLog>());
53 state.event_log_writer.reset(new EventLogWriter(
54 state.event_log.get(), kMinBitrateChangeBps, kMinBitrateChangeFraction,
55 kMinPacketLossChangeFraction));
56 state.runtime_config.bitrate_bps = kHighBitrateBps;
57 state.runtime_config.frame_length_ms = kFrameLengthMs;
58 state.runtime_config.uplink_packet_loss_fraction = kPacketLossFraction;
59 state.runtime_config.enable_fec = kEnableFec;
60 state.runtime_config.enable_dtx = kEnableDtx;
61 state.runtime_config.num_channels = kNumChannels;
62 return state;
63 }
64 } // namespace
65
TEST(EventLogWriterTest,FirstConfigIsLogged)66 TEST(EventLogWriterTest, FirstConfigIsLogged) {
67 auto state = CreateEventLogWriter();
68 EXPECT_CALL(*state.event_log,
69 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
70 .Times(1);
71 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
72 }
73
TEST(EventLogWriterTest,SameConfigIsNotLogged)74 TEST(EventLogWriterTest, SameConfigIsNotLogged) {
75 auto state = CreateEventLogWriter();
76 EXPECT_CALL(*state.event_log,
77 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
78 .Times(1);
79 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
80 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
81 }
82
TEST(EventLogWriterTest,LogFecStateChange)83 TEST(EventLogWriterTest, LogFecStateChange) {
84 auto state = CreateEventLogWriter();
85 EXPECT_CALL(*state.event_log,
86 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
87 .Times(1);
88 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
89
90 state.runtime_config.enable_fec = !kEnableFec;
91 EXPECT_CALL(*state.event_log,
92 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
93 .Times(1);
94 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
95 }
96
TEST(EventLogWriterTest,LogDtxStateChange)97 TEST(EventLogWriterTest, LogDtxStateChange) {
98 auto state = CreateEventLogWriter();
99 EXPECT_CALL(*state.event_log,
100 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
101 .Times(1);
102 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
103
104 state.runtime_config.enable_dtx = !kEnableDtx;
105 EXPECT_CALL(*state.event_log,
106 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
107 .Times(1);
108 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
109 }
110
TEST(EventLogWriterTest,LogChannelChange)111 TEST(EventLogWriterTest, LogChannelChange) {
112 auto state = CreateEventLogWriter();
113 EXPECT_CALL(*state.event_log,
114 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
115 .Times(1);
116 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
117
118 state.runtime_config.num_channels = kNumChannels + 1;
119 EXPECT_CALL(*state.event_log,
120 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
121 .Times(1);
122 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
123 }
124
TEST(EventLogWriterTest,LogFrameLengthChange)125 TEST(EventLogWriterTest, LogFrameLengthChange) {
126 auto state = CreateEventLogWriter();
127 EXPECT_CALL(*state.event_log,
128 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
129 .Times(1);
130 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
131
132 state.runtime_config.frame_length_ms = 20;
133 EXPECT_CALL(*state.event_log,
134 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
135 .Times(1);
136 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
137 }
138
TEST(EventLogWriterTest,DoNotLogSmallBitrateChange)139 TEST(EventLogWriterTest, DoNotLogSmallBitrateChange) {
140 auto state = CreateEventLogWriter();
141 EXPECT_CALL(*state.event_log,
142 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
143 .Times(1);
144 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
145 state.runtime_config.bitrate_bps = kHighBitrateBps + kMinBitrateChangeBps - 1;
146 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
147 }
148
TEST(EventLogWriterTest,LogLargeBitrateChange)149 TEST(EventLogWriterTest, LogLargeBitrateChange) {
150 auto state = CreateEventLogWriter();
151 EXPECT_CALL(*state.event_log,
152 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
153 .Times(1);
154 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
155 // At high bitrate, the min fraction rule requires a larger change than the
156 // min change rule. We make sure that the min change rule applies.
157 RTC_DCHECK_GT(kHighBitrateBps * kMinBitrateChangeFraction,
158 kMinBitrateChangeBps);
159 state.runtime_config.bitrate_bps = kHighBitrateBps + kMinBitrateChangeBps;
160 EXPECT_CALL(*state.event_log,
161 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
162 .Times(1);
163 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
164 }
165
TEST(EventLogWriterTest,LogMinBitrateChangeFractionOnLowBitrateChange)166 TEST(EventLogWriterTest, LogMinBitrateChangeFractionOnLowBitrateChange) {
167 auto state = CreateEventLogWriter();
168 state.runtime_config.bitrate_bps = kLowBitrateBps;
169 EXPECT_CALL(*state.event_log,
170 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
171 .Times(1);
172 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
173 // At high bitrate, the min change rule requires a larger change than the min
174 // fraction rule. We make sure that the min fraction rule applies.
175 state.runtime_config.bitrate_bps =
176 kLowBitrateBps + kLowBitrateBps * kMinBitrateChangeFraction;
177 EXPECT_CALL(*state.event_log,
178 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
179 .Times(1);
180 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
181 }
182
TEST(EventLogWriterTest,DoNotLogSmallPacketLossFractionChange)183 TEST(EventLogWriterTest, DoNotLogSmallPacketLossFractionChange) {
184 auto state = CreateEventLogWriter();
185 EXPECT_CALL(*state.event_log,
186 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
187 .Times(1);
188 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
189 state.runtime_config.uplink_packet_loss_fraction =
190 kPacketLossFraction + kMinPacketLossChangeFraction * kPacketLossFraction -
191 0.001f;
192 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
193 }
194
TEST(EventLogWriterTest,LogLargePacketLossFractionChange)195 TEST(EventLogWriterTest, LogLargePacketLossFractionChange) {
196 auto state = CreateEventLogWriter();
197 EXPECT_CALL(*state.event_log,
198 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
199 .Times(1);
200 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
201 state.runtime_config.uplink_packet_loss_fraction =
202 kPacketLossFraction + kMinPacketLossChangeFraction * kPacketLossFraction;
203 EXPECT_CALL(*state.event_log,
204 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
205 .Times(1);
206 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
207 }
208
TEST(EventLogWriterTest,LogJustOnceOnMultipleChanges)209 TEST(EventLogWriterTest, LogJustOnceOnMultipleChanges) {
210 auto state = CreateEventLogWriter();
211 EXPECT_CALL(*state.event_log,
212 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
213 .Times(1);
214 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
215 state.runtime_config.uplink_packet_loss_fraction =
216 kPacketLossFraction + kMinPacketLossChangeFraction * kPacketLossFraction;
217 state.runtime_config.frame_length_ms = 20;
218 EXPECT_CALL(*state.event_log,
219 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
220 .Times(1);
221 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
222 }
223
TEST(EventLogWriterTest,LogAfterGradualChange)224 TEST(EventLogWriterTest, LogAfterGradualChange) {
225 auto state = CreateEventLogWriter();
226 EXPECT_CALL(*state.event_log,
227 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
228 .Times(1);
229 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
230 state.runtime_config.bitrate_bps = kHighBitrateBps + kMinBitrateChangeBps;
231 EXPECT_CALL(*state.event_log,
232 LogProxy(IsRtcEventAnaConfigEqualTo(state.runtime_config)))
233 .Times(1);
234 for (int bitrate_bps = kHighBitrateBps;
235 bitrate_bps <= kHighBitrateBps + kMinBitrateChangeBps; bitrate_bps++) {
236 state.runtime_config.bitrate_bps = bitrate_bps;
237 state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
238 }
239 }
240 } // namespace webrtc
241