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:
Ivo Creusen 2019-10-07 13:18:18 +02:00 committed by Commit Bot
parent 35cf9e76a8
commit 99a2096248
7 changed files with 195 additions and 0 deletions

View File

@ -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);
}

View File

@ -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[]);

View File

@ -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",
]
}

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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