blob: 3b787a6cfbd4002bc4c185b8b1d98b27e4b97c57 [file] [log] [blame]
* Copyright (c) 2016 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 <fstream>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_decoder_factory.h"
#include "api/neteq/neteq.h"
#include "api/neteq/neteq_factory.h"
#include "api/test/neteq_simulator.h"
#include "modules/audio_coding/neteq/tools/audio_sink.h"
#include "modules/audio_coding/neteq/tools/neteq_input.h"
#include "system_wrappers/include/clock.h"
namespace webrtc {
namespace test {
class NetEqTestErrorCallback {
virtual ~NetEqTestErrorCallback() = default;
virtual void OnInsertPacketError(const NetEqInput::PacketData& packet) {}
virtual void OnGetAudioError() {}
class DefaultNetEqTestErrorCallback : public NetEqTestErrorCallback {
void OnInsertPacketError(const NetEqInput::PacketData& packet) override;
void OnGetAudioError() override;
class NetEqPostInsertPacket {
virtual ~NetEqPostInsertPacket() = default;
virtual void AfterInsertPacket(const NetEqInput::PacketData& packet,
NetEq* neteq) = 0;
class NetEqGetAudioCallback {
virtual ~NetEqGetAudioCallback() = default;
virtual void BeforeGetAudio(NetEq* neteq) = 0;
virtual void AfterGetAudio(int64_t time_now_ms,
const AudioFrame& audio_frame,
bool muted,
NetEq* neteq) = 0;
class NetEqSimulationEndedCallback {
virtual ~NetEqSimulationEndedCallback() = default;
virtual void SimulationEnded(int64_t simulation_time_ms, NetEq* neteq) = 0;
// Class that provides an input--output test for NetEq. The input (both packets
// and output events) is provided by a NetEqInput object, while the output is
// directed to an AudioSink object.
class NetEqTest : public NetEqSimulator {
using DecoderMap = std::map<int, SdpAudioFormat>;
struct Callbacks {
NetEqTestErrorCallback* error_callback = nullptr;
NetEqPostInsertPacket* post_insert_packet = nullptr;
NetEqGetAudioCallback* get_audio_callback = nullptr;
NetEqSimulationEndedCallback* simulation_ended_callback = nullptr;
// Sets up the test with given configuration, codec mappings, input, ouput,
// and callback objects for error reporting.
NetEqTest(const NetEq::Config& config,
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
const DecoderMap& codecs,
std::unique_ptr<std::ofstream> text_log,
NetEqFactory* neteq_factory,
std::unique_ptr<NetEqInput> input,
std::unique_ptr<AudioSink> output,
Callbacks callbacks);
~NetEqTest() override;
// Runs the test. Returns the duration of the produced audio in ms.
int64_t Run() override;
// Runs the simulation until we hit the next GetAudio event. If the simulation
// is finished, is_simulation_finished will be set to true in the returned
// SimulationStepResult.
SimulationStepResult RunToNextGetAudio() override;
void SetNextAction(Action next_operation) override;
NetEqState GetNetEqState() override;
// Returns the statistics from NetEq.
NetEqNetworkStatistics SimulationStats();
NetEqLifetimeStatistics LifetimeStats() const;
static DecoderMap StandardDecoderMap();
void RegisterDecoders(const DecoderMap& codecs);
SimulatedClock clock_;
absl::optional<Action> next_action_;
absl::optional<int> last_packet_time_ms_;
std::unique_ptr<NetEq> neteq_;
std::unique_ptr<NetEqInput> input_;
std::unique_ptr<AudioSink> output_;
Callbacks callbacks_;
int sample_rate_hz_;
NetEqState current_state_;
NetEqOperationsAndState prev_ops_state_;
NetEqLifetimeStatistics prev_lifetime_stats_;
absl::optional<uint32_t> last_packet_timestamp_;
std::unique_ptr<std::ofstream> text_log_;
} // namespace test
} // namespace webrtc