xref: /aosp_15_r20/external/webrtc/test/scenario/stats_collection_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/stats_collection.h"
11*d9f75844SAndroid Build Coastguard Worker 
12*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
13*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/scenario.h"
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
16*d9f75844SAndroid Build Coastguard Worker namespace test {
17*d9f75844SAndroid Build Coastguard Worker namespace {
CreateAnalyzedStream(Scenario * s,NetworkSimulationConfig network_config,VideoQualityAnalyzer * analyzer,CallStatsCollectors * collectors)18*d9f75844SAndroid Build Coastguard Worker void CreateAnalyzedStream(Scenario* s,
19*d9f75844SAndroid Build Coastguard Worker                           NetworkSimulationConfig network_config,
20*d9f75844SAndroid Build Coastguard Worker                           VideoQualityAnalyzer* analyzer,
21*d9f75844SAndroid Build Coastguard Worker                           CallStatsCollectors* collectors) {
22*d9f75844SAndroid Build Coastguard Worker   VideoStreamConfig config;
23*d9f75844SAndroid Build Coastguard Worker   config.encoder.codec = VideoStreamConfig::Encoder::Codec::kVideoCodecVP8;
24*d9f75844SAndroid Build Coastguard Worker   config.encoder.implementation =
25*d9f75844SAndroid Build Coastguard Worker       VideoStreamConfig::Encoder::Implementation::kSoftware;
26*d9f75844SAndroid Build Coastguard Worker   config.hooks.frame_pair_handlers = {analyzer->Handler()};
27*d9f75844SAndroid Build Coastguard Worker   auto* caller = s->CreateClient("caller", CallClientConfig());
28*d9f75844SAndroid Build Coastguard Worker   auto* callee = s->CreateClient("callee", CallClientConfig());
29*d9f75844SAndroid Build Coastguard Worker   auto route =
30*d9f75844SAndroid Build Coastguard Worker       s->CreateRoutes(caller, {s->CreateSimulationNode(network_config)}, callee,
31*d9f75844SAndroid Build Coastguard Worker                       {s->CreateSimulationNode(NetworkSimulationConfig())});
32*d9f75844SAndroid Build Coastguard Worker   VideoStreamPair* video = s->CreateVideoStream(route->forward(), config);
33*d9f75844SAndroid Build Coastguard Worker   auto* audio = s->CreateAudioStream(route->forward(), AudioStreamConfig());
34*d9f75844SAndroid Build Coastguard Worker   s->Every(TimeDelta::Seconds(1), [=] {
35*d9f75844SAndroid Build Coastguard Worker     collectors->call.AddStats(caller->GetStats());
36*d9f75844SAndroid Build Coastguard Worker 
37*d9f75844SAndroid Build Coastguard Worker     VideoSendStream::Stats send_stats;
38*d9f75844SAndroid Build Coastguard Worker     caller->SendTask([&]() { send_stats = video->send()->GetStats(); });
39*d9f75844SAndroid Build Coastguard Worker     collectors->video_send.AddStats(send_stats, s->Now());
40*d9f75844SAndroid Build Coastguard Worker 
41*d9f75844SAndroid Build Coastguard Worker     AudioReceiveStreamInterface::Stats receive_stats;
42*d9f75844SAndroid Build Coastguard Worker     caller->SendTask([&]() { receive_stats = audio->receive()->GetStats(); });
43*d9f75844SAndroid Build Coastguard Worker     collectors->audio_receive.AddStats(receive_stats);
44*d9f75844SAndroid Build Coastguard Worker 
45*d9f75844SAndroid Build Coastguard Worker     // Querying the video stats from within the expected runtime environment
46*d9f75844SAndroid Build Coastguard Worker     // (i.e. the TQ that belongs to the CallClient, not the Scenario TQ that
47*d9f75844SAndroid Build Coastguard Worker     // we're currently on).
48*d9f75844SAndroid Build Coastguard Worker     VideoReceiveStreamInterface::Stats video_receive_stats;
49*d9f75844SAndroid Build Coastguard Worker     auto* video_stream = video->receive();
50*d9f75844SAndroid Build Coastguard Worker     callee->SendTask([&video_stream, &video_receive_stats]() {
51*d9f75844SAndroid Build Coastguard Worker       video_receive_stats = video_stream->GetStats();
52*d9f75844SAndroid Build Coastguard Worker     });
53*d9f75844SAndroid Build Coastguard Worker     collectors->video_receive.AddStats(video_receive_stats);
54*d9f75844SAndroid Build Coastguard Worker   });
55*d9f75844SAndroid Build Coastguard Worker }
56*d9f75844SAndroid Build Coastguard Worker }  // namespace
57*d9f75844SAndroid Build Coastguard Worker 
TEST(ScenarioAnalyzerTest,PsnrIsHighWhenNetworkIsGood)58*d9f75844SAndroid Build Coastguard Worker TEST(ScenarioAnalyzerTest, PsnrIsHighWhenNetworkIsGood) {
59*d9f75844SAndroid Build Coastguard Worker   VideoQualityAnalyzer analyzer;
60*d9f75844SAndroid Build Coastguard Worker   CallStatsCollectors stats;
61*d9f75844SAndroid Build Coastguard Worker   {
62*d9f75844SAndroid Build Coastguard Worker     Scenario s;
63*d9f75844SAndroid Build Coastguard Worker     NetworkSimulationConfig good_network;
64*d9f75844SAndroid Build Coastguard Worker     good_network.bandwidth = DataRate::KilobitsPerSec(1000);
65*d9f75844SAndroid Build Coastguard Worker     CreateAnalyzedStream(&s, good_network, &analyzer, &stats);
66*d9f75844SAndroid Build Coastguard Worker     s.RunFor(TimeDelta::Seconds(3));
67*d9f75844SAndroid Build Coastguard Worker   }
68*d9f75844SAndroid Build Coastguard Worker   // This is a change detecting test, the targets are based on previous runs and
69*d9f75844SAndroid Build Coastguard Worker   // might change due to changes in configuration and encoder etc. The main
70*d9f75844SAndroid Build Coastguard Worker   // purpose is to show how the stats can be used. To avoid being overly
71*d9f75844SAndroid Build Coastguard Worker   // sensistive to change, the ranges are chosen to be quite large.
72*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(analyzer.stats().psnr_with_freeze.Mean(), 43, 10);
73*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(stats.call.stats().target_rate.Mean().kbps(), 700, 300);
74*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(stats.video_send.stats().media_bitrate.Mean().kbps(), 500, 200);
75*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(stats.video_receive.stats().resolution.Mean(), 180, 10);
76*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(stats.audio_receive.stats().jitter_buffer.Mean().ms(), 40, 20);
77*d9f75844SAndroid Build Coastguard Worker }
78*d9f75844SAndroid Build Coastguard Worker 
TEST(ScenarioAnalyzerTest,PsnrIsLowWhenNetworkIsBad)79*d9f75844SAndroid Build Coastguard Worker TEST(ScenarioAnalyzerTest, PsnrIsLowWhenNetworkIsBad) {
80*d9f75844SAndroid Build Coastguard Worker   VideoQualityAnalyzer analyzer;
81*d9f75844SAndroid Build Coastguard Worker   CallStatsCollectors stats;
82*d9f75844SAndroid Build Coastguard Worker   {
83*d9f75844SAndroid Build Coastguard Worker     Scenario s;
84*d9f75844SAndroid Build Coastguard Worker     NetworkSimulationConfig bad_network;
85*d9f75844SAndroid Build Coastguard Worker     bad_network.bandwidth = DataRate::KilobitsPerSec(100);
86*d9f75844SAndroid Build Coastguard Worker     bad_network.loss_rate = 0.02;
87*d9f75844SAndroid Build Coastguard Worker     CreateAnalyzedStream(&s, bad_network, &analyzer, &stats);
88*d9f75844SAndroid Build Coastguard Worker     s.RunFor(TimeDelta::Seconds(3));
89*d9f75844SAndroid Build Coastguard Worker   }
90*d9f75844SAndroid Build Coastguard Worker   // This is a change detecting test, the targets are based on previous runs and
91*d9f75844SAndroid Build Coastguard Worker   // might change due to changes in configuration and encoder etc.
92*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(analyzer.stats().psnr_with_freeze.Mean(), 20, 10);
93*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(stats.call.stats().target_rate.Mean().kbps(), 75, 50);
94*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(stats.video_send.stats().media_bitrate.Mean().kbps(), 100, 50);
95*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(stats.video_receive.stats().resolution.Mean(), 180, 10);
96*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(stats.audio_receive.stats().jitter_buffer.Mean().ms(), 250, 200);
97*d9f75844SAndroid Build Coastguard Worker }
98*d9f75844SAndroid Build Coastguard Worker 
TEST(ScenarioAnalyzerTest,CountsCapturedButNotRendered)99*d9f75844SAndroid Build Coastguard Worker TEST(ScenarioAnalyzerTest, CountsCapturedButNotRendered) {
100*d9f75844SAndroid Build Coastguard Worker   VideoQualityAnalyzer analyzer;
101*d9f75844SAndroid Build Coastguard Worker   CallStatsCollectors stats;
102*d9f75844SAndroid Build Coastguard Worker   {
103*d9f75844SAndroid Build Coastguard Worker     Scenario s;
104*d9f75844SAndroid Build Coastguard Worker     NetworkSimulationConfig long_delays;
105*d9f75844SAndroid Build Coastguard Worker     long_delays.delay = TimeDelta::Seconds(5);
106*d9f75844SAndroid Build Coastguard Worker     CreateAnalyzedStream(&s, long_delays, &analyzer, &stats);
107*d9f75844SAndroid Build Coastguard Worker     // Enough time to send frames but not enough to deliver.
108*d9f75844SAndroid Build Coastguard Worker     s.RunFor(TimeDelta::Millis(100));
109*d9f75844SAndroid Build Coastguard Worker   }
110*d9f75844SAndroid Build Coastguard Worker   EXPECT_GE(analyzer.stats().capture.count, 1);
111*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(analyzer.stats().render.count, 0);
112*d9f75844SAndroid Build Coastguard Worker }
113*d9f75844SAndroid Build Coastguard Worker }  // namespace test
114*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
115