blob: 96b2830c76db4a3cbd5e74d250b387d9bd547196 [file] [log] [blame]
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +01001/*
2 * Copyright 2018 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 */
Sebastian Jansson7150d8c2019-04-09 14:18:09 +020010#include "test/scenario/stats_collection.h"
Jonas Olssona4d87372019-07-05 19:08:33 +020011
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010012#include "test/gtest.h"
13#include "test/scenario/scenario.h"
14
15namespace webrtc {
16namespace test {
17namespace {
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020018void CreateAnalyzedStream(Scenario* s,
Sebastian Janssonef86d142019-04-15 14:42:42 +020019 NetworkSimulationConfig network_config,
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020020 VideoQualityAnalyzer* analyzer,
21 CallStatsCollectors* collectors) {
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010022 VideoStreamConfig config;
23 config.encoder.codec = VideoStreamConfig::Encoder::Codec::kVideoCodecVP8;
24 config.encoder.implementation =
25 VideoStreamConfig::Encoder::Implementation::kSoftware;
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020026 config.hooks.frame_pair_handlers = {analyzer->Handler()};
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020027 auto* caller = s->CreateClient("caller", CallClientConfig());
Tommi3c9bcc12020-04-15 16:45:47 +020028 auto* callee = s->CreateClient("callee", CallClientConfig());
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020029 auto route =
Tommi3c9bcc12020-04-15 16:45:47 +020030 s->CreateRoutes(caller, {s->CreateSimulationNode(network_config)}, callee,
Sebastian Janssonef86d142019-04-15 14:42:42 +020031 {s->CreateSimulationNode(NetworkSimulationConfig())});
Tommi3c9bcc12020-04-15 16:45:47 +020032 VideoStreamPair* video = s->CreateVideoStream(route->forward(), config);
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020033 auto* audio = s->CreateAudioStream(route->forward(), AudioStreamConfig());
Danil Chapovalov0c626af2020-02-10 11:16:00 +010034 s->Every(TimeDelta::Seconds(1), [=] {
Sebastian Janssondab21c62019-05-13 11:48:40 +020035 collectors->call.AddStats(caller->GetStats());
Tomas Gunnarsson788d8052021-05-03 16:23:08 +020036
37 VideoSendStream::Stats send_stats;
38 caller->SendTask([&]() { send_stats = video->send()->GetStats(); });
39 collectors->video_send.AddStats(send_stats, s->Now());
40
41 AudioReceiveStream::Stats receive_stats;
42 caller->SendTask([&]() { receive_stats = audio->receive()->GetStats(); });
43 collectors->audio_receive.AddStats(receive_stats);
Tommi3c9bcc12020-04-15 16:45:47 +020044
45 // Querying the video stats from within the expected runtime environment
46 // (i.e. the TQ that belongs to the CallClient, not the Scenario TQ that
47 // we're currently on).
48 VideoReceiveStream::Stats video_receive_stats;
49 auto* video_stream = video->receive();
50 callee->SendTask([&video_stream, &video_receive_stats]() {
51 video_receive_stats = video_stream->GetStats();
52 });
53 collectors->video_receive.AddStats(video_receive_stats);
Sebastian Janssondab21c62019-05-13 11:48:40 +020054 });
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010055}
56} // namespace
57
58TEST(ScenarioAnalyzerTest, PsnrIsHighWhenNetworkIsGood) {
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020059 VideoQualityAnalyzer analyzer;
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020060 CallStatsCollectors stats;
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010061 {
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020062 Scenario s;
Sebastian Janssonef86d142019-04-15 14:42:42 +020063 NetworkSimulationConfig good_network;
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +010064 good_network.bandwidth = DataRate::KilobitsPerSec(1000);
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020065 CreateAnalyzedStream(&s, good_network, &analyzer, &stats);
Danil Chapovalov0c626af2020-02-10 11:16:00 +010066 s.RunFor(TimeDelta::Seconds(3));
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010067 }
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020068 // This is a change detecting test, the targets are based on previous runs and
69 // might change due to changes in configuration and encoder etc. The main
70 // purpose is to show how the stats can be used. To avoid being overly
71 // sensistive to change, the ranges are chosen to be quite large.
Sebastian Janssone9cac4f2019-06-24 17:10:55 +020072 EXPECT_NEAR(analyzer.stats().psnr_with_freeze.Mean(), 43, 10);
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020073 EXPECT_NEAR(stats.call.stats().target_rate.Mean().kbps(), 700, 300);
74 EXPECT_NEAR(stats.video_send.stats().media_bitrate.Mean().kbps(), 500, 200);
75 EXPECT_NEAR(stats.video_receive.stats().resolution.Mean(), 180, 10);
76 EXPECT_NEAR(stats.audio_receive.stats().jitter_buffer.Mean().ms(), 40, 20);
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010077}
78
79TEST(ScenarioAnalyzerTest, PsnrIsLowWhenNetworkIsBad) {
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020080 VideoQualityAnalyzer analyzer;
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020081 CallStatsCollectors stats;
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010082 {
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020083 Scenario s;
Sebastian Janssonef86d142019-04-15 14:42:42 +020084 NetworkSimulationConfig bad_network;
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +010085 bad_network.bandwidth = DataRate::KilobitsPerSec(100);
Sebastian Janssonef86d142019-04-15 14:42:42 +020086 bad_network.loss_rate = 0.02;
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020087 CreateAnalyzedStream(&s, bad_network, &analyzer, &stats);
Danil Chapovalov0c626af2020-02-10 11:16:00 +010088 s.RunFor(TimeDelta::Seconds(3));
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010089 }
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020090 // This is a change detecting test, the targets are based on previous runs and
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020091 // might change due to changes in configuration and encoder etc.
Erik Språnge886d2e2020-04-16 15:07:56 +020092 EXPECT_NEAR(analyzer.stats().psnr_with_freeze.Mean(), 20, 10);
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020093 EXPECT_NEAR(stats.call.stats().target_rate.Mean().kbps(), 75, 50);
94 EXPECT_NEAR(stats.video_send.stats().media_bitrate.Mean().kbps(), 100, 50);
95 EXPECT_NEAR(stats.video_receive.stats().resolution.Mean(), 180, 10);
Ying Wangf4fa7632021-02-08 18:03:23 +010096 EXPECT_NEAR(stats.audio_receive.stats().jitter_buffer.Mean().ms(), 250, 200);
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010097}
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020098
Sebastian Janssondab21c62019-05-13 11:48:40 +020099TEST(ScenarioAnalyzerTest, CountsCapturedButNotRendered) {
100 VideoQualityAnalyzer analyzer;
101 CallStatsCollectors stats;
102 {
103 Scenario s;
104 NetworkSimulationConfig long_delays;
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100105 long_delays.delay = TimeDelta::Seconds(5);
Sebastian Janssondab21c62019-05-13 11:48:40 +0200106 CreateAnalyzedStream(&s, long_delays, &analyzer, &stats);
107 // Enough time to send frames but not enough to deliver.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100108 s.RunFor(TimeDelta::Millis(100));
Sebastian Janssondab21c62019-05-13 11:48:40 +0200109 }
110 EXPECT_GE(analyzer.stats().capture.count, 1);
111 EXPECT_EQ(analyzer.stats().render.count, 0);
112}
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +0100113} // namespace test
114} // namespace webrtc