1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
/*
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "audio/test/audio_end_to_end_test.h"
#include "rtc_base/numerics/safe_compare.h"
#include "system_wrappers/include/sleep.h"
#include "test/gtest.h"
namespace webrtc {
namespace test {
namespace {
// Wait half a second between stopping sending and stopping receiving audio.
constexpr int kExtraRecordTimeMs = 500;
bool IsNear(int reference, int v) {
// Margin is 10%.
const int error = reference / 10 + 1;
return std::abs(reference - v) <= error;
}
class NoLossTest : public AudioEndToEndTest {
public:
const int kTestDurationMs = 8000;
const int kBytesSent = 69351;
const int32_t kPacketsSent = 400;
const int64_t kRttMs = 100;
NoLossTest() = default;
BuiltInNetworkBehaviorConfig GetSendTransportConfig() const override {
BuiltInNetworkBehaviorConfig pipe_config;
pipe_config.queue_delay_ms = kRttMs / 2;
return pipe_config;
}
void PerformTest() override {
SleepMs(kTestDurationMs);
send_audio_device()->StopRecording();
// and some extra time to account for network delay.
SleepMs(GetSendTransportConfig().queue_delay_ms + kExtraRecordTimeMs);
}
void OnStreamsStopped() override {
AudioSendStream::Stats send_stats = send_stream()->GetStats();
EXPECT_PRED2(IsNear, kBytesSent, send_stats.payload_bytes_sent);
EXPECT_PRED2(IsNear, kPacketsSent, send_stats.packets_sent);
EXPECT_EQ(0, send_stats.packets_lost);
EXPECT_EQ(0.0f, send_stats.fraction_lost);
EXPECT_EQ("opus", send_stats.codec_name);
// send_stats.jitter_ms
EXPECT_PRED2(IsNear, kRttMs, send_stats.rtt_ms);
// Send level is 0 because it is cleared in TransmitMixer::StopSend().
EXPECT_EQ(0, send_stats.audio_level);
// send_stats.total_input_energy
// send_stats.total_input_duration
EXPECT_FALSE(send_stats.apm_statistics.delay_median_ms);
EXPECT_FALSE(send_stats.apm_statistics.delay_standard_deviation_ms);
EXPECT_FALSE(send_stats.apm_statistics.echo_return_loss);
EXPECT_FALSE(send_stats.apm_statistics.echo_return_loss_enhancement);
EXPECT_FALSE(send_stats.apm_statistics.residual_echo_likelihood);
EXPECT_FALSE(send_stats.apm_statistics.residual_echo_likelihood_recent_max);
AudioReceiveStreamInterface::Stats recv_stats =
receive_stream()->GetStats(/*get_and_clear_legacy_stats=*/true);
EXPECT_PRED2(IsNear, kBytesSent, recv_stats.payload_bytes_received);
EXPECT_PRED2(IsNear, kPacketsSent, recv_stats.packets_received);
EXPECT_EQ(0, recv_stats.packets_lost);
EXPECT_EQ("opus", send_stats.codec_name);
// recv_stats.jitter_ms
// recv_stats.jitter_buffer_ms
EXPECT_EQ(20u, recv_stats.jitter_buffer_preferred_ms);
// recv_stats.delay_estimate_ms
// Receive level is 0 because it is cleared in Channel::StopPlayout().
EXPECT_EQ(0, recv_stats.audio_level);
// recv_stats.total_output_energy
// recv_stats.total_samples_received
// recv_stats.total_output_duration
// recv_stats.concealed_samples
// recv_stats.expand_rate
// recv_stats.speech_expand_rate
EXPECT_EQ(0.0, recv_stats.secondary_decoded_rate);
EXPECT_EQ(0.0, recv_stats.secondary_discarded_rate);
EXPECT_EQ(0.0, recv_stats.accelerate_rate);
EXPECT_EQ(0.0, recv_stats.preemptive_expand_rate);
EXPECT_EQ(0, recv_stats.decoding_calls_to_silence_generator);
// recv_stats.decoding_calls_to_neteq
// recv_stats.decoding_normal
// recv_stats.decoding_plc
EXPECT_EQ(0, recv_stats.decoding_cng);
// recv_stats.decoding_plc_cng
// recv_stats.decoding_muted_output
// Capture start time is -1 because we do not have an associated send stream
// on the receiver side.
EXPECT_EQ(-1, recv_stats.capture_start_ntp_time_ms);
// Match these stats between caller and receiver.
EXPECT_EQ(send_stats.local_ssrc, recv_stats.remote_ssrc);
EXPECT_EQ(*send_stats.codec_payload_type, *recv_stats.codec_payload_type);
}
};
} // namespace
using AudioStatsTest = CallTest;
TEST_F(AudioStatsTest, DISABLED_NoLoss) {
NoLossTest test;
RunBaseTest(&test);
}
} // namespace test
} // namespace webrtc
|