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}
This commit is contained in:
parent
35cf9e76a8
commit
99a2096248
@ -60,6 +60,9 @@ std::unique_ptr<NetEqSimulator> NetEqSimulatorFactory::CreateSimulatorFromFile(
|
||||
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 @@ NetEqSimulatorFactory::CreateSimulatorFromString(
|
||||
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);
|
||||
}
|
||||
|
||||
@ -27,7 +27,19 @@ class NetEqSimulatorFactory {
|
||||
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[]);
|
||||
|
||||
@ -1070,6 +1070,8 @@ rtc_source_set("neteq_test_tools") {
|
||||
"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 @@ if (rtc_include_tests) {
|
||||
"../../api/audio_codecs:builtin_audio_decoder_factory",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../test:audio_codec_mocks",
|
||||
"../../test:field_trial",
|
||||
"../../test:test_support",
|
||||
]
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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 @@ std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTest(
|
||||
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 @@ std::unique_ptr<NetEqTest> NetEqTestFactory::InitializeTest(
|
||||
<< 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
|
||||
|
||||
@ -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 @@ class NetEqTestFactory {
|
||||
// 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 @@ class NetEqTestFactory {
|
||||
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 @@ class NetEqTestFactory {
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user