109 lines
4.5 KiB
C++
109 lines
4.5 KiB
C++
/*
|
|
* Copyright 2018 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 "test/scenario/stats_collection.h"
|
|
|
|
#include "test/gtest.h"
|
|
#include "test/scenario/scenario.h"
|
|
|
|
namespace webrtc {
|
|
namespace test {
|
|
namespace {
|
|
void CreateAnalyzedStream(Scenario* s,
|
|
NetworkSimulationConfig network_config,
|
|
VideoQualityAnalyzer* analyzer,
|
|
CallStatsCollectors* collectors) {
|
|
VideoStreamConfig config;
|
|
config.encoder.codec = VideoStreamConfig::Encoder::Codec::kVideoCodecVP8;
|
|
config.encoder.implementation =
|
|
VideoStreamConfig::Encoder::Implementation::kSoftware;
|
|
config.hooks.frame_pair_handlers = {analyzer->Handler()};
|
|
auto* caller = s->CreateClient("caller", CallClientConfig());
|
|
auto* callee = s->CreateClient("callee", CallClientConfig());
|
|
auto route =
|
|
s->CreateRoutes(caller, {s->CreateSimulationNode(network_config)}, callee,
|
|
{s->CreateSimulationNode(NetworkSimulationConfig())});
|
|
VideoStreamPair* video = s->CreateVideoStream(route->forward(), config);
|
|
auto* audio = s->CreateAudioStream(route->forward(), AudioStreamConfig());
|
|
s->Every(TimeDelta::Seconds(1), [=] {
|
|
collectors->call.AddStats(caller->GetStats());
|
|
collectors->video_send.AddStats(video->send()->GetStats(), s->Now());
|
|
collectors->audio_receive.AddStats(audio->receive()->GetStats());
|
|
|
|
// Querying the video stats from within the expected runtime environment
|
|
// (i.e. the TQ that belongs to the CallClient, not the Scenario TQ that
|
|
// we're currently on).
|
|
VideoReceiveStream::Stats video_receive_stats;
|
|
auto* video_stream = video->receive();
|
|
callee->SendTask([&video_stream, &video_receive_stats]() {
|
|
video_receive_stats = video_stream->GetStats();
|
|
});
|
|
collectors->video_receive.AddStats(video_receive_stats);
|
|
});
|
|
}
|
|
} // namespace
|
|
|
|
TEST(ScenarioAnalyzerTest, PsnrIsHighWhenNetworkIsGood) {
|
|
VideoQualityAnalyzer analyzer;
|
|
CallStatsCollectors stats;
|
|
{
|
|
Scenario s;
|
|
NetworkSimulationConfig good_network;
|
|
good_network.bandwidth = DataRate::KilobitsPerSec(1000);
|
|
CreateAnalyzedStream(&s, good_network, &analyzer, &stats);
|
|
s.RunFor(TimeDelta::Seconds(3));
|
|
}
|
|
// This is a change detecting test, the targets are based on previous runs and
|
|
// might change due to changes in configuration and encoder etc. The main
|
|
// purpose is to show how the stats can be used. To avoid being overly
|
|
// sensistive to change, the ranges are chosen to be quite large.
|
|
EXPECT_NEAR(analyzer.stats().psnr_with_freeze.Mean(), 43, 10);
|
|
EXPECT_NEAR(stats.call.stats().target_rate.Mean().kbps(), 700, 300);
|
|
EXPECT_NEAR(stats.video_send.stats().media_bitrate.Mean().kbps(), 500, 200);
|
|
EXPECT_NEAR(stats.video_receive.stats().resolution.Mean(), 180, 10);
|
|
EXPECT_NEAR(stats.audio_receive.stats().jitter_buffer.Mean().ms(), 40, 20);
|
|
}
|
|
|
|
TEST(ScenarioAnalyzerTest, PsnrIsLowWhenNetworkIsBad) {
|
|
VideoQualityAnalyzer analyzer;
|
|
CallStatsCollectors stats;
|
|
{
|
|
Scenario s;
|
|
NetworkSimulationConfig bad_network;
|
|
bad_network.bandwidth = DataRate::KilobitsPerSec(100);
|
|
bad_network.loss_rate = 0.02;
|
|
CreateAnalyzedStream(&s, bad_network, &analyzer, &stats);
|
|
s.RunFor(TimeDelta::Seconds(3));
|
|
}
|
|
// This is a change detecting test, the targets are based on previous runs and
|
|
// might change due to changes in configuration and encoder etc.
|
|
EXPECT_NEAR(analyzer.stats().psnr_with_freeze.Mean(), 20, 10);
|
|
EXPECT_NEAR(stats.call.stats().target_rate.Mean().kbps(), 75, 50);
|
|
EXPECT_NEAR(stats.video_send.stats().media_bitrate.Mean().kbps(), 100, 50);
|
|
EXPECT_NEAR(stats.video_receive.stats().resolution.Mean(), 180, 10);
|
|
EXPECT_NEAR(stats.audio_receive.stats().jitter_buffer.Mean().ms(), 200, 150);
|
|
}
|
|
|
|
TEST(ScenarioAnalyzerTest, CountsCapturedButNotRendered) {
|
|
VideoQualityAnalyzer analyzer;
|
|
CallStatsCollectors stats;
|
|
{
|
|
Scenario s;
|
|
NetworkSimulationConfig long_delays;
|
|
long_delays.delay = TimeDelta::Seconds(5);
|
|
CreateAnalyzedStream(&s, long_delays, &analyzer, &stats);
|
|
// Enough time to send frames but not enough to deliver.
|
|
s.RunFor(TimeDelta::Millis(100));
|
|
}
|
|
EXPECT_GE(analyzer.stats().capture.count, 1);
|
|
EXPECT_EQ(analyzer.stats().render.count, 0);
|
|
}
|
|
} // namespace test
|
|
} // namespace webrtc
|