Allow passing an event log as string to NetEqSimulator.

Previously only reading from the filesystem was supported, this CL
allows parsing an event log from a string.

Bug: webrtc:10337
Change-Id: Iadde3319eb8fb4175625f510201fac9c01c80ed9
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/127296
Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
Reviewed-by: Minyue Li <minyue@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27202}
This commit is contained in:
Ivo Creusen
2019-03-20 10:52:18 +01:00
committed by Commit Bot
parent 9b9b25386b
commit 5ec61565cb
10 changed files with 122 additions and 29 deletions

View File

@ -421,6 +421,7 @@ if (rtc_include_tests) {
"../rtc_base:checks",
"../rtc_base:rtc_base_approved",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/strings",
]
}
}

View File

@ -50,7 +50,30 @@ std::unique_ptr<NetEqSimulator> NetEqSimulatorFactory::CreateSimulator(
config.replacement_audio_file = FLAG_replacement_audio_file;
config.max_nr_packets_in_buffer = FLAG_max_nr_packets_in_buffer;
config.output_audio_filename = output_audio_filename;
return factory_->InitializeTest(argv[1], config);
return factory_->InitializeTestFromFile(argv[1], config);
}
std::unique_ptr<NetEqSimulator> NetEqSimulatorFactory::CreateSimulatorFromFile(
absl::string_view event_log_filename,
absl::string_view replacement_audio_filename,
Config simulation_config) {
NetEqTestFactory::Config config;
config.replacement_audio_file = std::string(replacement_audio_filename);
config.max_nr_packets_in_buffer = simulation_config.max_nr_packets_in_buffer;
return factory_->InitializeTestFromFile(std::string(event_log_filename),
config);
}
std::unique_ptr<NetEqSimulator>
NetEqSimulatorFactory::CreateSimulatorFromString(
absl::string_view event_log_file_contents,
absl::string_view replacement_audio_filename,
Config simulation_config) {
NetEqTestFactory::Config config;
config.replacement_audio_file = std::string(replacement_audio_filename);
config.max_nr_packets_in_buffer = simulation_config.max_nr_packets_in_buffer;
return factory_->InitializeTestFromString(
std::string(event_log_file_contents), config);
}
} // namespace test

View File

@ -12,7 +12,9 @@
#define API_TEST_NETEQ_SIMULATOR_FACTORY_H_
#include <memory>
#include <string>
#include "absl/strings/string_view.h"
#include "api/test/neteq_simulator.h"
namespace webrtc {
@ -24,8 +26,20 @@ class NetEqSimulatorFactory {
public:
NetEqSimulatorFactory();
~NetEqSimulatorFactory();
struct Config {
int max_nr_packets_in_buffer = 0;
};
// This function takes the same arguments as the neteq_rtpplay utility.
std::unique_ptr<NetEqSimulator> CreateSimulator(int argc, char* argv[]);
std::unique_ptr<NetEqSimulator> CreateSimulatorFromFile(
absl::string_view event_log_filename,
absl::string_view replacement_audio_filename,
Config simulation_config);
// The same as above, but pass the file contents as a string.
std::unique_ptr<NetEqSimulator> CreateSimulatorFromString(
absl::string_view event_log_file_contents,
absl::string_view replacement_audio_file,
Config simulation_config);
private:
std::unique_ptr<NetEqTestFactory> factory_;

View File

@ -11,6 +11,7 @@
#include "modules/audio_coding/neteq/tools/neteq_event_log_input.h"
#include <limits>
#include <memory>
#include "modules/audio_coding/neteq/tools/rtc_event_log_source.h"
#include "rtc_base/checks.h"
@ -18,11 +19,18 @@
namespace webrtc {
namespace test {
NetEqEventLogInput::NetEqEventLogInput(const std::string& file_name,
absl::optional<uint32_t> ssrc_filter)
: source_(RtcEventLogSource::Create(file_name, ssrc_filter)) {
LoadNextPacket();
AdvanceOutputEvent();
NetEqEventLogInput* NetEqEventLogInput::CreateFromFile(
const std::string& file_name,
absl::optional<uint32_t> ssrc_filter) {
return new NetEqEventLogInput(
RtcEventLogSource::CreateFromFile(file_name, ssrc_filter));
}
NetEqEventLogInput* NetEqEventLogInput::CreateFromString(
const std::string& file_contents,
absl::optional<uint32_t> ssrc_filter) {
return new NetEqEventLogInput(
RtcEventLogSource::CreateFromString(file_contents, ssrc_filter));
}
absl::optional<int64_t> NetEqEventLogInput::NextOutputEventTime() const {
@ -40,5 +48,12 @@ PacketSource* NetEqEventLogInput::source() {
return source_.get();
}
NetEqEventLogInput::NetEqEventLogInput(
std::unique_ptr<RtcEventLogSource> source)
: source_(std::move(source)) {
LoadNextPacket();
AdvanceOutputEvent();
}
} // namespace test
} // namespace webrtc

View File

@ -27,8 +27,12 @@ class RtcEventLogSource;
// RtcEventLogSource.
class NetEqEventLogInput final : public NetEqPacketSourceInput {
public:
NetEqEventLogInput(const std::string& file_name,
absl::optional<uint32_t> ssrc_filter);
static NetEqEventLogInput* CreateFromFile(
const std::string& file_name,
absl::optional<uint32_t> ssrc_filter);
static NetEqEventLogInput* CreateFromString(
const std::string& file_contents,
absl::optional<uint32_t> ssrc_filter);
absl::optional<int64_t> NextOutputEventTime() const override;
void AdvanceOutputEvent() override;
@ -37,6 +41,7 @@ class NetEqEventLogInput final : public NetEqPacketSourceInput {
PacketSource* source() override;
private:
NetEqEventLogInput(std::unique_ptr<RtcEventLogSource> source);
std::unique_ptr<RtcEventLogSource> source_;
};

View File

@ -377,8 +377,8 @@ int main(int argc, char* argv[]) {
config.ssrc_filter = absl::make_optional(ssrc);
}
std::unique_ptr<webrtc::test::NetEqTest> test = factory.InitializeTest(
/*input_filename=*/argv[1], config);
std::unique_ptr<webrtc::test::NetEqTest> test =
factory.InitializeTestFromFile(/*input_filename=*/argv[1], config);
test->Run();
return 0;
}

View File

@ -108,8 +108,17 @@ NetEqTestFactory::Config::Config() = default;
NetEqTestFactory::Config::Config(const Config& other) = default;
NetEqTestFactory::Config::~Config() = default;
std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTest(
std::string input_file_name,
std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTestFromString(
const std::string& input_string,
const Config& config) {
std::unique_ptr<NetEqInput> input(
NetEqEventLogInput::CreateFromString(input_string, config.ssrc_filter));
RTC_CHECK(input) << "Cannot parse input string";
return InitializeTest(std::move(input), config);
}
std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTestFromFile(
const std::string& input_file_name,
const Config& config) {
// Gather RTP header extensions in a map.
NetEqPacketSourceInput::RtpHeaderExtensionMap rtp_ext_map = {
@ -125,12 +134,19 @@ std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTest(
input.reset(new NetEqRtpDumpInput(input_file_name, rtp_ext_map,
config.ssrc_filter));
} else {
input.reset(new NetEqEventLogInput(input_file_name, config.ssrc_filter));
input.reset(NetEqEventLogInput::CreateFromFile(input_file_name,
config.ssrc_filter));
}
std::cout << "Input file: " << input_file_name << std::endl;
RTC_CHECK(input) << "Cannot open input file";
RTC_CHECK(!input->ended()) << "Input file is empty";
return InitializeTest(std::move(input), config);
}
std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTest(
std::unique_ptr<NetEqInput> input,
const Config& config) {
RTC_CHECK(!input->ended()) << "Input is empty";
// Check the sample rate.
absl::optional<int> sample_rate_hz;

View File

@ -133,10 +133,16 @@ class NetEqTestFactory {
absl::optional<std::string> output_audio_filename;
};
std::unique_ptr<NetEqTest> InitializeTest(std::string input_filename,
const Config& config);
std::unique_ptr<NetEqTest> InitializeTestFromFile(
const std::string& input_filename,
const Config& config);
std::unique_ptr<NetEqTest> InitializeTestFromString(
const std::string& input_string,
const Config& config);
private:
std::unique_ptr<NetEqTest> InitializeTest(std::unique_ptr<NetEqInput> input,
const Config& config);
std::unique_ptr<SsrcSwitchDetector> ssrc_switch_detector_;
std::unique_ptr<NetEqStatsPlotter> stats_plotter_;
};

View File

@ -36,11 +36,23 @@ bool ShouldSkipStream(ParsedRtcEventLog::MediaType media_type,
}
} // namespace
RtcEventLogSource* RtcEventLogSource::Create(
std::unique_ptr<RtcEventLogSource> RtcEventLogSource::CreateFromFile(
const std::string& file_name,
absl::optional<uint32_t> ssrc_filter) {
RtcEventLogSource* source = new RtcEventLogSource();
RTC_CHECK(source->OpenFile(file_name, ssrc_filter));
auto source = std::unique_ptr<RtcEventLogSource>(new RtcEventLogSource());
ParsedRtcEventLog parsed_log;
RTC_CHECK(parsed_log.ParseFile(file_name));
RTC_CHECK(source->Initialize(parsed_log, ssrc_filter));
return source;
}
std::unique_ptr<RtcEventLogSource> RtcEventLogSource::CreateFromString(
const std::string& file_contents,
absl::optional<uint32_t> ssrc_filter) {
auto source = std::unique_ptr<RtcEventLogSource>(new RtcEventLogSource());
ParsedRtcEventLog parsed_log;
RTC_CHECK(parsed_log.ParseString(file_contents));
RTC_CHECK(source->Initialize(parsed_log, ssrc_filter));
return source;
}
@ -64,12 +76,8 @@ int64_t RtcEventLogSource::NextAudioOutputEventMs() {
RtcEventLogSource::RtcEventLogSource() : PacketSource() {}
bool RtcEventLogSource::OpenFile(const std::string& file_name,
absl::optional<uint32_t> ssrc_filter) {
ParsedRtcEventLog parsed_log;
if (!parsed_log.ParseFile(file_name))
return false;
bool RtcEventLogSource::Initialize(const ParsedRtcEventLog& parsed_log,
absl::optional<uint32_t> ssrc_filter) {
const auto first_log_end_time_us =
parsed_log.stop_log_events().empty()
? std::numeric_limits<int64_t>::max()

View File

@ -33,8 +33,13 @@ class RtcEventLogSource : public PacketSource {
public:
// Creates an RtcEventLogSource reading from |file_name|. If the file cannot
// be opened, or has the wrong format, NULL will be returned.
static RtcEventLogSource* Create(const std::string& file_name,
absl::optional<uint32_t> ssrc_filter);
static std::unique_ptr<RtcEventLogSource> CreateFromFile(
const std::string& file_name,
absl::optional<uint32_t> ssrc_filter);
// Same as above, but uses a string with the file contents.
static std::unique_ptr<RtcEventLogSource> CreateFromString(
const std::string& file_contents,
absl::optional<uint32_t> ssrc_filter);
virtual ~RtcEventLogSource();
@ -48,8 +53,8 @@ class RtcEventLogSource : public PacketSource {
private:
RtcEventLogSource();
bool OpenFile(const std::string& file_name,
absl::optional<uint32_t> ssrc_filter);
bool Initialize(const ParsedRtcEventLog& parsed_log,
absl::optional<uint32_t> ssrc_filter);
std::vector<std::unique_ptr<Packet>> rtp_packets_;
size_t rtp_packet_index_ = 0;