Added support for skipping get_audio events, adding dummy packets and setting a field trial string.
Bug: webrtc:10337
Change-Id: I0507da4d955daa914af774c946be16a4168be21a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/150780
Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Minyue Li <minyue@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29392}
diff --git a/api/test/neteq_simulator_factory.cc b/api/test/neteq_simulator_factory.cc
index 112d55a..9a751a4 100644
--- a/api/test/neteq_simulator_factory.cc
+++ b/api/test/neteq_simulator_factory.cc
@@ -60,6 +60,9 @@
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;
+ config.initial_dummy_packets = simulation_config.initial_dummy_packets;
+ config.skip_get_audio_events = simulation_config.skip_get_audio_events;
+ config.field_trial_string = simulation_config.field_trial_string;
return factory_->InitializeTestFromFile(std::string(event_log_filename),
config);
}
@@ -72,6 +75,9 @@
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;
+ config.initial_dummy_packets = simulation_config.initial_dummy_packets;
+ config.skip_get_audio_events = simulation_config.skip_get_audio_events;
+ config.field_trial_string = simulation_config.field_trial_string;
return factory_->InitializeTestFromString(
std::string(event_log_file_contents), config);
}
diff --git a/api/test/neteq_simulator_factory.h b/api/test/neteq_simulator_factory.h
index 245162f..3c0cbe0 100644
--- a/api/test/neteq_simulator_factory.h
+++ b/api/test/neteq_simulator_factory.h
@@ -27,7 +27,19 @@
NetEqSimulatorFactory();
~NetEqSimulatorFactory();
struct Config {
+ // The maximum allowed number of packets in the jitter buffer.
int max_nr_packets_in_buffer = 0;
+ // The number of audio packets to insert at the start of the simulation.
+ // Since the simulation is done with a replacement audio file, these
+ // artificial packets will take a small piece of that replacement audio.
+ int initial_dummy_packets = 0;
+ // The number of simulation steps to skip at the start of the simulation.
+ // This removes incoming packets and GetAudio events from the start of the
+ // simulation, until the requested number of GetAudio events has been
+ // removed.
+ int skip_get_audio_events = 0;
+ // A WebRTC field trial string to be used during the simulation.
+ std::string field_trial_string;
};
// This function takes the same arguments as the neteq_rtpplay utility.
std::unique_ptr<NetEqSimulator> CreateSimulator(int argc, char* argv[]);
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index e90ffc8..06bcbde 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -1070,6 +1070,8 @@
"neteq/tools/audio_loop.h",
"neteq/tools/constant_pcm_packet_source.cc",
"neteq/tools/constant_pcm_packet_source.h",
+ "neteq/tools/initial_packet_inserter_neteq_input.cc",
+ "neteq/tools/initial_packet_inserter_neteq_input.h",
"neteq/tools/neteq_packet_source_input.cc",
"neteq/tools/neteq_packet_source_input.h",
"neteq/tools/output_audio_file.h",
@@ -1466,6 +1468,7 @@
"../../api/audio_codecs:builtin_audio_decoder_factory",
"../../rtc_base:rtc_base_approved",
"../../test:audio_codec_mocks",
+ "../../test:field_trial",
"../../test:test_support",
]
}
diff --git a/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.cc b/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.cc
new file mode 100644
index 0000000..3c33aab
--- /dev/null
+++ b/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.cc
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019 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 "modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.h"
+
+#include <limits>
+#include <memory>
+#include <utility>
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+namespace test {
+
+InitialPacketInserterNetEqInput::InitialPacketInserterNetEqInput(
+ std::unique_ptr<NetEqInput> source,
+ int number_of_initial_packets,
+ int sample_rate_hz)
+ : source_(std::move(source)),
+ packets_to_insert_(number_of_initial_packets),
+ sample_rate_hz_(sample_rate_hz) {}
+
+absl::optional<int64_t> InitialPacketInserterNetEqInput::NextPacketTime()
+ const {
+ return source_->NextPacketTime();
+}
+
+absl::optional<int64_t> InitialPacketInserterNetEqInput::NextOutputEventTime()
+ const {
+ return source_->NextOutputEventTime();
+}
+
+std::unique_ptr<InitialPacketInserterNetEqInput::PacketData>
+InitialPacketInserterNetEqInput::PopPacket() {
+ if (!first_packet_) {
+ first_packet_ = source_->PopPacket();
+ if (!first_packet_) {
+ // The source has no packets, so we should not insert any dummy packets.
+ packets_to_insert_ = 0;
+ }
+ }
+ if (packets_to_insert_ > 0) {
+ RTC_CHECK(first_packet_);
+ auto dummy_packet = std::unique_ptr<PacketData>(new PacketData());
+ dummy_packet->header = first_packet_->header;
+ dummy_packet->payload = rtc::Buffer(first_packet_->payload.data(),
+ first_packet_->payload.size());
+ dummy_packet->time_ms = first_packet_->time_ms;
+ dummy_packet->header.sequenceNumber -= packets_to_insert_;
+ // This assumes 20ms per packet.
+ dummy_packet->header.timestamp -=
+ 20 * sample_rate_hz_ * packets_to_insert_ / 1000;
+ packets_to_insert_--;
+ return dummy_packet;
+ }
+ return source_->PopPacket();
+}
+
+void InitialPacketInserterNetEqInput::AdvanceOutputEvent() {
+ source_->AdvanceOutputEvent();
+}
+
+bool InitialPacketInserterNetEqInput::ended() const {
+ return source_->ended();
+}
+
+absl::optional<RTPHeader> InitialPacketInserterNetEqInput::NextHeader() const {
+ return source_->NextHeader();
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.h b/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.h
new file mode 100644
index 0000000..bd20a7a
--- /dev/null
+++ b/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#ifndef MODULES_AUDIO_CODING_NETEQ_TOOLS_INITIAL_PACKET_INSERTER_NETEQ_INPUT_H_
+#define MODULES_AUDIO_CODING_NETEQ_TOOLS_INITIAL_PACKET_INSERTER_NETEQ_INPUT_H_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "modules/audio_coding/neteq/tools/neteq_input.h"
+
+namespace webrtc {
+namespace test {
+
+// Wrapper class that can insert a number of packets at the start of the
+// simulation.
+class InitialPacketInserterNetEqInput final : public NetEqInput {
+ public:
+ InitialPacketInserterNetEqInput(std::unique_ptr<NetEqInput> source,
+ int number_of_initial_packets,
+ int sample_rate_hz);
+ absl::optional<int64_t> NextPacketTime() const override;
+ absl::optional<int64_t> NextOutputEventTime() const override;
+ std::unique_ptr<PacketData> PopPacket() override;
+ void AdvanceOutputEvent() override;
+ bool ended() const override;
+ absl::optional<RTPHeader> NextHeader() const override;
+
+ private:
+ const std::unique_ptr<NetEqInput> source_;
+ int packets_to_insert_;
+ const int sample_rate_hz_;
+ std::unique_ptr<PacketData> first_packet_;
+};
+
+} // namespace test
+} // namespace webrtc
+#endif // MODULES_AUDIO_CODING_NETEQ_TOOLS_INITIAL_PACKET_INSERTER_NETEQ_INPUT_H_
diff --git a/modules/audio_coding/neteq/tools/neteq_test_factory.cc b/modules/audio_coding/neteq/tools/neteq_test_factory.cc
index 3c3add4..c50f7d9 100644
--- a/modules/audio_coding/neteq/tools/neteq_test_factory.cc
+++ b/modules/audio_coding/neteq/tools/neteq_test_factory.cc
@@ -26,6 +26,7 @@
#include "modules/audio_coding/neteq/include/neteq.h"
#include "modules/audio_coding/neteq/tools/audio_sink.h"
#include "modules/audio_coding/neteq/tools/fake_decode_from_file.h"
+#include "modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.h"
#include "modules/audio_coding/neteq/tools/input_audio_file.h"
#include "modules/audio_coding/neteq/tools/neteq_delay_analyzer.h"
#include "modules/audio_coding/neteq/tools/neteq_event_log_input.h"
@@ -156,6 +157,35 @@
return nullptr;
}
+ if (!config.field_trial_string.empty()) {
+ field_trials_ =
+ std::make_unique<ScopedFieldTrials>(config.field_trial_string);
+ }
+
+ // Skip some initial events/packets if requested.
+ if (config.skip_get_audio_events > 0) {
+ std::cout << "Skipping " << config.skip_get_audio_events
+ << " get_audio events" << std::endl;
+ if (!input->NextPacketTime() || !input->NextOutputEventTime()) {
+ std::cerr << "No events found" << std::endl;
+ return nullptr;
+ }
+ for (int i = 0; i < config.skip_get_audio_events; i++) {
+ input->AdvanceOutputEvent();
+ if (!input->NextOutputEventTime()) {
+ std::cerr << "Not enough get_audio events found" << std::endl;
+ return nullptr;
+ }
+ }
+ while (*input->NextPacketTime() < *input->NextOutputEventTime()) {
+ input->PopPacket();
+ if (!input->NextPacketTime()) {
+ std::cerr << "Not enough incoming packets found" << std::endl;
+ return nullptr;
+ }
+ }
+ }
+
// Check the sample rate.
absl::optional<int> sample_rate_hz;
std::set<std::pair<int, uint32_t>> discarded_pt_and_ssrc;
@@ -167,6 +197,12 @@
<< static_cast<int>(first_rtp_header->payloadType)
<< " and SSRC 0x" << std::hex << first_rtp_header->ssrc
<< std::dec << std::endl;
+ if (config.initial_dummy_packets > 0) {
+ std::cout << "Nr of initial dummy packets: "
+ << config.initial_dummy_packets << std::endl;
+ input = std::make_unique<InitialPacketInserterNetEqInput>(
+ std::move(input), config.initial_dummy_packets, *sample_rate_hz);
+ }
break;
}
// Discard this packet and move to the next. Keep track of discarded payload
diff --git a/modules/audio_coding/neteq/tools/neteq_test_factory.h b/modules/audio_coding/neteq/tools/neteq_test_factory.h
index 34b7c77..3f59f6b 100644
--- a/modules/audio_coding/neteq/tools/neteq_test_factory.h
+++ b/modules/audio_coding/neteq/tools/neteq_test_factory.h
@@ -16,6 +16,7 @@
#include "absl/types/optional.h"
#include "modules/audio_coding/neteq/tools/neteq_test.h"
+#include "test/field_trial.h"
namespace webrtc {
namespace test {
@@ -122,6 +123,13 @@
// Maximum allowed number of packets in the buffer.
static constexpr int default_max_nr_packets_in_buffer() { return 50; }
int max_nr_packets_in_buffer = default_max_nr_packets_in_buffer();
+ // Number of dummy packets to put in the packet buffer at the start of the
+ // simulation.
+ static constexpr int default_initial_dummy_packets() { return 0; }
+ int initial_dummy_packets = default_initial_dummy_packets();
+ // Number of getAudio events to skip at the start of the simulation.
+ static constexpr int default_skip_get_audio_events() { return 0; }
+ int skip_get_audio_events = default_skip_get_audio_events();
// Enables jitter buffer fast accelerate.
bool enable_fast_accelerate = false;
// Path to the output text log file that describes the simulation on a
@@ -131,6 +139,8 @@
absl::optional<std::string> plot_scripts_basename;
// Path to the output audio file.
absl::optional<std::string> output_audio_filename;
+ // Field trials to use during the simulation.
+ std::string field_trial_string;
};
std::unique_ptr<NetEqTest> InitializeTestFromFile(
@@ -145,6 +155,9 @@
const Config& config);
std::unique_ptr<SsrcSwitchDetector> ssrc_switch_detector_;
std::unique_ptr<NetEqStatsPlotter> stats_plotter_;
+ // The field trials are stored in the test factory, because neteq_test is not
+ // in a testonly target, and therefore cannot use ScopedFieldTrials.
+ std::unique_ptr<ScopedFieldTrials> field_trials_;
};
} // namespace test