Enable using a custom NetEqFactory in simulations

Bug: webrtc:11005
Change-Id: I8a15f77953cbd3c29a75c7cfc77f926b138994b9
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/165580
Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30286}
This commit is contained in:
Ivo Creusen 2020-01-16 17:17:09 +01:00 committed by Commit Bot
parent 658f1814da
commit 2a11b2451a
13 changed files with 44 additions and 19 deletions

View file

@ -678,6 +678,7 @@ if (rtc_include_tests) {
":neteq_simulator_api", ":neteq_simulator_api",
"../modules/audio_coding:neteq_test_factory", "../modules/audio_coding:neteq_test_factory",
"../rtc_base:checks", "../rtc_base:checks",
"neteq:neteq_api",
"//third_party/abseil-cpp/absl/flags:flag", "//third_party/abseil-cpp/absl/flags:flag",
"//third_party/abseil-cpp/absl/flags:parse", "//third_party/abseil-cpp/absl/flags:parse",
"//third_party/abseil-cpp/absl/strings", "//third_party/abseil-cpp/absl/strings",

View file

@ -50,7 +50,8 @@ std::unique_ptr<NetEqSimulator> NetEqSimulatorFactory::CreateSimulator(
config.max_nr_packets_in_buffer = config.max_nr_packets_in_buffer =
absl::GetFlag(FLAGS_max_nr_packets_in_buffer); absl::GetFlag(FLAGS_max_nr_packets_in_buffer);
config.output_audio_filename = output_audio_filename; config.output_audio_filename = output_audio_filename;
return factory_->InitializeTestFromFile(args[1], config); return factory_->InitializeTestFromFile(/*input_file_name=*/args[1],
/*factory=*/nullptr, config);
} }
std::unique_ptr<NetEqSimulator> NetEqSimulatorFactory::CreateSimulatorFromFile( std::unique_ptr<NetEqSimulator> NetEqSimulatorFactory::CreateSimulatorFromFile(
@ -63,8 +64,8 @@ std::unique_ptr<NetEqSimulator> NetEqSimulatorFactory::CreateSimulatorFromFile(
config.initial_dummy_packets = simulation_config.initial_dummy_packets; config.initial_dummy_packets = simulation_config.initial_dummy_packets;
config.skip_get_audio_events = simulation_config.skip_get_audio_events; config.skip_get_audio_events = simulation_config.skip_get_audio_events;
config.field_trial_string = simulation_config.field_trial_string; config.field_trial_string = simulation_config.field_trial_string;
return factory_->InitializeTestFromFile(std::string(event_log_filename), return factory_->InitializeTestFromFile(
config); std::string(event_log_filename), simulation_config.neteq_factory, config);
} }
std::unique_ptr<NetEqSimulator> std::unique_ptr<NetEqSimulator>
@ -79,7 +80,8 @@ NetEqSimulatorFactory::CreateSimulatorFromString(
config.skip_get_audio_events = simulation_config.skip_get_audio_events; config.skip_get_audio_events = simulation_config.skip_get_audio_events;
config.field_trial_string = simulation_config.field_trial_string; config.field_trial_string = simulation_config.field_trial_string;
return factory_->InitializeTestFromString( return factory_->InitializeTestFromString(
std::string(event_log_file_contents), config); std::string(event_log_file_contents), simulation_config.neteq_factory,
config);
} }
} // namespace test } // namespace test

View file

@ -15,6 +15,7 @@
#include <string> #include <string>
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "api/neteq/neteq_factory.h"
#include "api/test/neteq_simulator.h" #include "api/test/neteq_simulator.h"
namespace webrtc { namespace webrtc {
@ -40,6 +41,8 @@ class NetEqSimulatorFactory {
int skip_get_audio_events = 0; int skip_get_audio_events = 0;
// A WebRTC field trial string to be used during the simulation. // A WebRTC field trial string to be used during the simulation.
std::string field_trial_string; std::string field_trial_string;
// A custom NetEqFactory can be used.
NetEqFactory* neteq_factory = nullptr;
}; };
// This function takes the same arguments as the neteq_rtpplay utility. // This function takes the same arguments as the neteq_rtpplay utility.
std::unique_ptr<NetEqSimulator> CreateSimulator(int argc, char* argv[]); std::unique_ptr<NetEqSimulator> CreateSimulator(int argc, char* argv[]);

View file

@ -186,8 +186,10 @@ NetEqNetworkStatistics RunTest(int loss_cadence, std::string* checksum) {
NetEqTest::Callbacks callbacks; NetEqTest::Callbacks callbacks;
NetEqTest neteq_test( NetEqTest neteq_test(
config, new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&dec), config, /*decoder_factory=*/
decoders, nullptr, std::move(lossy_input), std::move(output), callbacks); new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&dec),
/*codecs=*/decoders, /*text_log=*/nullptr, /*neteq_factory=*/nullptr,
/*input=*/std::move(lossy_input), std::move(output), callbacks);
EXPECT_LE(kRunTimeMs, neteq_test.Run()); EXPECT_LE(kRunTimeMs, neteq_test.Run());
auto lifetime_stats = neteq_test.LifetimeStats(); auto lifetime_stats = neteq_test.LifetimeStats();

View file

@ -1084,8 +1084,10 @@ TEST(NetEqNoTimeStretchingMode, RunTest) {
new TimeLimitedNetEqInput(std::move(input), 20000)); new TimeLimitedNetEqInput(std::move(input), 20000));
std::unique_ptr<AudioSink> output(new VoidAudioSink); std::unique_ptr<AudioSink> output(new VoidAudioSink);
NetEqTest::Callbacks callbacks; NetEqTest::Callbacks callbacks;
NetEqTest test(config, CreateBuiltinAudioDecoderFactory(), codecs, nullptr, NetEqTest test(config, CreateBuiltinAudioDecoderFactory(), codecs,
std::move(input_time_limit), std::move(output), callbacks); /*text_log=*/nullptr, /*neteq_factory=*/nullptr,
/*input=*/std::move(input_time_limit), std::move(output),
callbacks);
test.Run(); test.Run();
const auto stats = test.SimulationStats(); const auto stats = test.SimulationStats();
EXPECT_EQ(0, stats.accelerate_rate); EXPECT_EQ(0, stats.accelerate_rate);

View file

@ -397,7 +397,8 @@ int main(int argc, char* argv[]) {
} }
std::unique_ptr<webrtc::test::NetEqTest> test = std::unique_ptr<webrtc::test::NetEqTest> test =
factory.InitializeTestFromFile(/*input_filename=*/args[1], config); factory.InitializeTestFromFile(/*input_filename=*/args[1],
/*factory=*/nullptr, config);
RTC_CHECK(test) << "ERROR: Unable to run test"; RTC_CHECK(test) << "ERROR: Unable to run test";
test->Run(); test->Run();
return 0; return 0;

View file

@ -63,11 +63,14 @@ NetEqTest::NetEqTest(const NetEq::Config& config,
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory, rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
const DecoderMap& codecs, const DecoderMap& codecs,
std::unique_ptr<std::ofstream> text_log, std::unique_ptr<std::ofstream> text_log,
NetEqFactory* neteq_factory,
std::unique_ptr<NetEqInput> input, std::unique_ptr<NetEqInput> input,
std::unique_ptr<AudioSink> output, std::unique_ptr<AudioSink> output,
Callbacks callbacks) Callbacks callbacks)
: clock_(0), : clock_(0),
neteq_(CreateNetEq(config, &clock_, decoder_factory)), neteq_(neteq_factory
? neteq_factory->CreateNetEq(config, decoder_factory, &clock_)
: CreateNetEq(config, &clock_, decoder_factory)),
input_(std::move(input)), input_(std::move(input)),
output_(std::move(output)), output_(std::move(output)),
callbacks_(callbacks), callbacks_(callbacks),

View file

@ -20,6 +20,7 @@
#include "absl/types/optional.h" #include "absl/types/optional.h"
#include "api/audio_codecs/audio_decoder_factory.h" #include "api/audio_codecs/audio_decoder_factory.h"
#include "api/neteq/neteq.h" #include "api/neteq/neteq.h"
#include "api/neteq/neteq_factory.h"
#include "api/test/neteq_simulator.h" #include "api/test/neteq_simulator.h"
#include "modules/audio_coding/neteq/tools/audio_sink.h" #include "modules/audio_coding/neteq/tools/audio_sink.h"
#include "modules/audio_coding/neteq/tools/neteq_input.h" #include "modules/audio_coding/neteq/tools/neteq_input.h"
@ -83,6 +84,7 @@ class NetEqTest : public NetEqSimulator {
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory, rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
const DecoderMap& codecs, const DecoderMap& codecs,
std::unique_ptr<std::ofstream> text_log, std::unique_ptr<std::ofstream> text_log,
NetEqFactory* neteq_factory,
std::unique_ptr<NetEqInput> input, std::unique_ptr<NetEqInput> input,
std::unique_ptr<AudioSink> output, std::unique_ptr<AudioSink> output,
Callbacks callbacks); Callbacks callbacks);

View file

@ -110,6 +110,7 @@ NetEqTestFactory::Config::~Config() = default;
std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTestFromString( std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTestFromString(
const std::string& input_string, const std::string& input_string,
NetEqFactory* factory,
const Config& config) { const Config& config) {
std::unique_ptr<NetEqInput> input( std::unique_ptr<NetEqInput> input(
NetEqEventLogInput::CreateFromString(input_string, config.ssrc_filter)); NetEqEventLogInput::CreateFromString(input_string, config.ssrc_filter));
@ -117,11 +118,12 @@ std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTestFromString(
std::cerr << "Error: Cannot parse input string" << std::endl; std::cerr << "Error: Cannot parse input string" << std::endl;
return nullptr; return nullptr;
} }
return InitializeTest(std::move(input), config); return InitializeTest(std::move(input), factory, config);
} }
std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTestFromFile( std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTestFromFile(
const std::string& input_file_name, const std::string& input_file_name,
NetEqFactory* factory,
const Config& config) { const Config& config) {
// Gather RTP header extensions in a map. // Gather RTP header extensions in a map.
NetEqPacketSourceInput::RtpHeaderExtensionMap rtp_ext_map = { NetEqPacketSourceInput::RtpHeaderExtensionMap rtp_ext_map = {
@ -146,11 +148,12 @@ std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTestFromFile(
std::cerr << "Error: Cannot open input file" << std::endl; std::cerr << "Error: Cannot open input file" << std::endl;
return nullptr; return nullptr;
} }
return InitializeTest(std::move(input), config); return InitializeTest(std::move(input), factory, config);
} }
std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTest( std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTest(
std::unique_ptr<NetEqInput> input, std::unique_ptr<NetEqInput> input,
NetEqFactory* factory,
const Config& config) { const Config& config) {
if (input->ended()) { if (input->ended()) {
std::cerr << "Error: Input is empty" << std::endl; std::cerr << "Error: Input is empty" << std::endl;
@ -330,9 +333,9 @@ std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTest(
neteq_config.sample_rate_hz = *sample_rate_hz; neteq_config.sample_rate_hz = *sample_rate_hz;
neteq_config.max_packets_in_buffer = config.max_nr_packets_in_buffer; neteq_config.max_packets_in_buffer = config.max_nr_packets_in_buffer;
neteq_config.enable_fast_accelerate = config.enable_fast_accelerate; neteq_config.enable_fast_accelerate = config.enable_fast_accelerate;
return std::make_unique<NetEqTest>(neteq_config, decoder_factory, codecs, return std::make_unique<NetEqTest>(
std::move(text_log), std::move(input), neteq_config, decoder_factory, codecs, std::move(text_log), factory,
std::move(output), callbacks); std::move(input), std::move(output), callbacks);
} }
} // namespace test } // namespace test

View file

@ -147,13 +147,16 @@ class NetEqTestFactory {
std::unique_ptr<NetEqTest> InitializeTestFromFile( std::unique_ptr<NetEqTest> InitializeTestFromFile(
const std::string& input_filename, const std::string& input_filename,
NetEqFactory* neteq_factory,
const Config& config); const Config& config);
std::unique_ptr<NetEqTest> InitializeTestFromString( std::unique_ptr<NetEqTest> InitializeTestFromString(
const std::string& input_string, const std::string& input_string,
NetEqFactory* neteq_factory,
const Config& config); const Config& config);
private: private:
std::unique_ptr<NetEqTest> InitializeTest(std::unique_ptr<NetEqInput> input, std::unique_ptr<NetEqTest> InitializeTest(std::unique_ptr<NetEqInput> input,
NetEqFactory* neteq_factory,
const Config& config); const Config& config);
std::unique_ptr<SsrcSwitchDetector> ssrc_switch_detector_; std::unique_ptr<SsrcSwitchDetector> ssrc_switch_detector_;
std::unique_ptr<NetEqStatsPlotter> stats_plotter_; std::unique_ptr<NetEqStatsPlotter> stats_plotter_;

View file

@ -1934,8 +1934,9 @@ std::unique_ptr<test::NetEqStatsGetter> CreateNetEqTestAndRun(
callbacks.post_insert_packet = neteq_stats_getter->delay_analyzer(); callbacks.post_insert_packet = neteq_stats_getter->delay_analyzer();
callbacks.get_audio_callback = neteq_stats_getter.get(); callbacks.get_audio_callback = neteq_stats_getter.get();
test::NetEqTest test(config, decoder_factory, codecs, nullptr, test::NetEqTest test(config, decoder_factory, codecs, /*text_log=*/nullptr,
std::move(input), std::move(output), callbacks); /*factory=*/nullptr, std::move(input), std::move(output),
callbacks);
test.Run(); test.Run();
return neteq_stats_getter; return neteq_stats_getter;
} }

View file

@ -138,7 +138,8 @@ void FuzzOneInputTest(const uint8_t* data, size_t size) {
RTC_CHECK(it != codecs.end()); RTC_CHECK(it != codecs.end());
RTC_CHECK(it->second == SdpAudioFormat("L16", 32000, 1)); RTC_CHECK(it->second == SdpAudioFormat("L16", 32000, 1));
NetEqTest test(config, CreateBuiltinAudioDecoderFactory(), codecs, nullptr, NetEqTest test(config, CreateBuiltinAudioDecoderFactory(), codecs,
/*text_log=*/nullptr, /*neteq_factory=*/nullptr,
std::move(input), std::move(output), callbacks); std::move(input), std::move(output), callbacks);
test.Run(); test.Run();
} }

View file

@ -186,7 +186,8 @@ void FuzzOneInputTest(const uint8_t* data, size_t size) {
RTC_CHECK( RTC_CHECK(
MapHas(codecs, rate_types[3].second, SdpAudioFormat("l16", 48000, 1))); MapHas(codecs, rate_types[3].second, SdpAudioFormat("l16", 48000, 1)));
NetEqTest test(config, CreateBuiltinAudioDecoderFactory(), codecs, nullptr, NetEqTest test(config, CreateBuiltinAudioDecoderFactory(), codecs,
/*text_log=*/nullptr, /*neteq_factory=*/nullptr,
std::move(input), std::move(output), callbacks); std::move(input), std::move(output), callbacks);
test.Run(); test.Run();
} }