Add support of overriding network simulation in video quality tests.

Add ability to provide custom implementation of
NetworkSimulatedInterface for sender and receiver network in
VideoQualityTestFixtureInterface, passing them to the factory method.
Also unite this mechanism with FecControllerFactoryInterface injection.


Bug: webrtc:9630
Change-Id: I79259113e0fc00d933b73ca299afa836a4cd19d2
Reviewed-on: https://webrtc-review.googlesource.com/96280
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Patrik Höglund <phoglund@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24476}
This commit is contained in:
Artem Titov
2018-08-29 09:59:23 +02:00
committed by Commit Bot
parent 55e7785686
commit e269cb4fe2
5 changed files with 92 additions and 31 deletions

View File

@ -26,7 +26,16 @@ CreateVideoQualityTestFixture() {
std::unique_ptr<VideoQualityTestFixtureInterface>
CreateVideoQualityTestFixture(
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory) {
return absl::make_unique<VideoQualityTest>(std::move(fec_controller_factory));
auto components = absl::make_unique<
VideoQualityTestFixtureInterface::InjectionComponents>();
components->fec_controller_factory = std::move(fec_controller_factory);
return absl::make_unique<VideoQualityTest>(std::move(components));
}
std::unique_ptr<VideoQualityTestFixtureInterface> CreateVideoQualityTestFixture(
std::unique_ptr<VideoQualityTestFixtureInterface::InjectionComponents>
components) {
return absl::make_unique<VideoQualityTest>(std::move(components));
}
} // namespace webrtc

View File

@ -24,6 +24,9 @@ std::unique_ptr<VideoQualityTestFixtureInterface>
CreateVideoQualityTestFixture(
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory);
}
std::unique_ptr<VideoQualityTestFixtureInterface> CreateVideoQualityTestFixture(
std::unique_ptr<VideoQualityTestFixtureInterface::InjectionComponents>
components);
} // namespace webrtc
#endif // API_TEST_CREATE_VIDEO_QUALITY_TEST_FIXTURE_H_

View File

@ -84,8 +84,10 @@ class VideoQualityTestFixtureInterface {
// it is just configuration, that will be passed to default implementation
// of simulation layer.
DefaultNetworkSimulationConfig pipe;
// Config for default simulation implementation. May be nullopt in that
// case, a default config will be used.
// Config for default simulation implementation. Must be nullopt if
// `sender_network` and `receiver_network` in InjectionComponents are
// non-null. May be nullopt even if `sender_network` and `receiver_network`
// are null; in that case, a default config will be used.
absl::optional<DefaultNetworkSimulationConfig> config;
struct SS { // Spatial scalability.
std::vector<VideoStream> streams; // If empty, one stream is assumed.
@ -105,6 +107,21 @@ class VideoQualityTestFixtureInterface {
} logging;
};
// Contains objects, that will be injected on different layers of test
// framework to override the behavior of system parts.
struct InjectionComponents {
InjectionComponents();
~InjectionComponents();
// Simulations of sender and receiver networks. They must either both be
// null (in which case `config` from Params is used), or both be non-null
// (in which case `config` from Params must be nullopt).
std::unique_ptr<NetworkSimulationInterface> sender_network;
std::unique_ptr<NetworkSimulationInterface> receiver_network;
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory;
};
virtual ~VideoQualityTestFixtureInterface() = default;
virtual void RunWithAnalyzer(const Params& params) = 0;

View File

@ -87,13 +87,18 @@ std::unique_ptr<VideoEncoder> VideoQualityTest::CreateVideoEncoder(
}
VideoQualityTest::VideoQualityTest(
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory)
std::unique_ptr<InjectionComponents> injection_components)
: clock_(Clock::GetRealTimeClock()),
video_encoder_factory_([this](const SdpVideoFormat& format) {
return this->CreateVideoEncoder(format);
}),
receive_logs_(0),
send_logs_(0) {
send_logs_(0),
injection_components_(std::move(injection_components)) {
if (injection_components_ == nullptr) {
injection_components_ = absl::make_unique<InjectionComponents>();
}
payload_type_map_ = test::CallTest::payload_type_map_;
RTC_DCHECK(payload_type_map_.find(kPayloadTypeH264) ==
payload_type_map_.end());
@ -105,7 +110,8 @@ VideoQualityTest::VideoQualityTest(
payload_type_map_[kPayloadTypeVP8] = webrtc::MediaType::VIDEO;
payload_type_map_[kPayloadTypeVP9] = webrtc::MediaType::VIDEO;
fec_controller_factory_ = std::move(fec_controller_factory);
fec_controller_factory_ =
std::move(injection_components_->fec_controller_factory);
}
VideoQualityTest::Params::Params()
@ -127,6 +133,10 @@ VideoQualityTest::Params::Params()
VideoQualityTest::Params::~Params() = default;
VideoQualityTest::InjectionComponents::InjectionComponents() = default;
VideoQualityTest::InjectionComponents::~InjectionComponents() = default;
void VideoQualityTest::TestBody() {}
std::string VideoQualityTest::GenerateGraphTitle() const {
@ -144,12 +154,21 @@ std::string VideoQualityTest::GenerateGraphTitle() const {
return ss.str();
}
void VideoQualityTest::CheckParams() {
if (!params_.config) {
void VideoQualityTest::CheckParamsAndInjectionComponents() {
if (injection_components_ == nullptr) {
injection_components_ = absl::make_unique<InjectionComponents>();
}
if (!params_.config && injection_components_->sender_network == nullptr &&
injection_components_->receiver_network == nullptr) {
// TODO(titovartem) replace with default config creation when removing
// pipe.
params_.config = params_.pipe;
}
RTC_CHECK(
(params_.config && injection_components_->sender_network == nullptr &&
injection_components_->receiver_network == nullptr) ||
(!params_.config && injection_components_->sender_network != nullptr &&
injection_components_->receiver_network != nullptr));
for (size_t video_idx = 0; video_idx < num_video_streams_; ++video_idx) {
// Iterate over primary and secondary video streams.
if (!params_.video[video_idx].enabled)
@ -161,6 +180,7 @@ void VideoQualityTest::CheckParams() {
if (params_.ss[video_idx].num_spatial_layers == 0)
params_.ss[video_idx].num_spatial_layers = 1;
if (params_.config) {
if (params_.config->loss_percent != 0 ||
params_.config->queue_length_packets != 0) {
// Since LayerFilteringTransport changes the sequence numbers, we can't
@ -173,6 +193,7 @@ void VideoQualityTest::CheckParams() {
params_.video[video_idx].selected_tl ==
params_.video[video_idx].num_temporal_layers - 1);
}
}
// TODO(ivica): Should max_bitrate_bps == -1 represent inf max bitrate, as
// it does in some parts of the code?
@ -312,7 +333,7 @@ void VideoQualityTest::FillScalabilitySettings(
} else {
// Read VideoStream and SpatialLayer elements from a list of comma separated
// lists. To use a default value for an element, use -1 or leave empty.
// Validity checks performed in CheckParams.
// Validity checks performed in CheckParamsAndInjectionComponents.
RTC_CHECK(params->ss[video_idx].streams.empty());
for (auto descriptor : stream_descriptors) {
if (descriptor.empty())
@ -804,11 +825,16 @@ void VideoQualityTest::StopThumbnails() {
std::unique_ptr<test::LayerFilteringTransport>
VideoQualityTest::CreateSendTransport() {
std::unique_ptr<NetworkSimulationInterface> simulated_network = nullptr;
if (injection_components_->sender_network == nullptr) {
simulated_network = absl::make_unique<SimulatedNetwork>(*params_.config);
} else {
simulated_network = std::move(injection_components_->sender_network);
}
return absl::make_unique<test::LayerFilteringTransport>(
&task_queue_,
absl::make_unique<FakeNetworkPipe>(
Clock::GetRealTimeClock(),
absl::make_unique<SimulatedNetwork>(*params_.config)),
absl::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
std::move(simulated_network)),
sender_call_.get(), kPayloadTypeVP8, kPayloadTypeVP9,
params_.video[0].selected_tl, params_.ss[0].selected_sl,
payload_type_map_, kVideoSendSsrcs[0],
@ -818,11 +844,16 @@ VideoQualityTest::CreateSendTransport() {
std::unique_ptr<test::DirectTransport>
VideoQualityTest::CreateReceiveTransport() {
std::unique_ptr<NetworkSimulationInterface> simulated_network = nullptr;
if (injection_components_->receiver_network == nullptr) {
simulated_network = absl::make_unique<SimulatedNetwork>(*params_.config);
} else {
simulated_network = std::move(injection_components_->receiver_network);
}
return absl::make_unique<test::DirectTransport>(
&task_queue_,
absl::make_unique<FakeNetworkPipe>(
Clock::GetRealTimeClock(),
absl::make_unique<SimulatedNetwork>(*params_.config)),
absl::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
std::move(simulated_network)),
receiver_call_.get(), payload_type_map_);
}
@ -836,7 +867,7 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) {
params_ = params;
// TODO(ivica): Merge with RunWithRenderer and use a flag / argument to
// differentiate between the analyzer and the renderer case.
CheckParams();
CheckParamsAndInjectionComponents();
if (!params_.analyzer.graph_data_output_filename.empty()) {
graph_data_output_file =
@ -1074,7 +1105,7 @@ void VideoQualityTest::RunWithRenderers(const Params& params) {
task_queue_.SendTask([&]() {
params_ = params;
CheckParams();
CheckParamsAndInjectionComponents();
// TODO(ivica): Remove bitrate_config and use the default Call::Config(), to
// match the full stack tests.

View File

@ -32,7 +32,7 @@ class VideoQualityTest :
public test::CallTest, public VideoQualityTestFixtureInterface {
public:
explicit VideoQualityTest(
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory);
std::unique_ptr<InjectionComponents> injection_components);
void RunWithAnalyzer(const Params& params) override;
void RunWithRenderers(const Params& params) override;
@ -66,7 +66,7 @@ class VideoQualityTest :
// Helper methods accessing only params_.
std::string GenerateGraphTitle() const;
void CheckParams();
void CheckParamsAndInjectionComponents();
// Helper methods for setting up the call.
void CreateCapturers();
@ -110,6 +110,7 @@ class VideoQualityTest :
int send_logs_;
Params params_;
std::unique_ptr<InjectionComponents> injection_components_;
// Note: not same as similarly named member in CallTest. This is the number of
// separate send streams, the one in CallTest is the number of substreams for