Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
95
TMessagesProj/jni/voip/webrtc/api/neteq/BUILD.gn
Normal file
95
TMessagesProj/jni/voip/webrtc/api/neteq/BUILD.gn
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
# 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.
|
||||
|
||||
import("../../webrtc.gni")
|
||||
|
||||
rtc_source_set("neteq_api") {
|
||||
visibility = [ "*" ]
|
||||
sources = [
|
||||
"neteq.cc",
|
||||
"neteq.h",
|
||||
"neteq_factory.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"..:rtp_headers",
|
||||
"..:rtp_packet_info",
|
||||
"..:scoped_refptr",
|
||||
"../../rtc_base:stringutils",
|
||||
"../../system_wrappers:system_wrappers",
|
||||
"../audio_codecs:audio_codecs_api",
|
||||
]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||
}
|
||||
|
||||
rtc_source_set("custom_neteq_factory") {
|
||||
visibility = [ "*" ]
|
||||
sources = [
|
||||
"custom_neteq_factory.cc",
|
||||
"custom_neteq_factory.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":neteq_api",
|
||||
":neteq_controller_api",
|
||||
"..:scoped_refptr",
|
||||
"../../modules/audio_coding:neteq",
|
||||
"../../system_wrappers:system_wrappers",
|
||||
"../audio_codecs:audio_codecs_api",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("neteq_controller_api") {
|
||||
visibility = [ "*" ]
|
||||
sources = [
|
||||
"neteq_controller.h",
|
||||
"neteq_controller_factory.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":neteq_api",
|
||||
":tick_timer",
|
||||
"../../system_wrappers:system_wrappers",
|
||||
]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||
}
|
||||
|
||||
rtc_source_set("default_neteq_controller_factory") {
|
||||
visibility = [ "*" ]
|
||||
sources = [
|
||||
"default_neteq_controller_factory.cc",
|
||||
"default_neteq_controller_factory.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":neteq_controller_api",
|
||||
"../../modules/audio_coding:neteq",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("tick_timer") {
|
||||
visibility = [ "*" ]
|
||||
sources = [
|
||||
"tick_timer.cc",
|
||||
"tick_timer.h",
|
||||
]
|
||||
deps = [
|
||||
"../../rtc_base:checks",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("tick_timer_unittest") {
|
||||
visibility = [ "*" ]
|
||||
testonly = true
|
||||
sources = [ "tick_timer_unittest.cc" ]
|
||||
deps = [
|
||||
":tick_timer",
|
||||
"../../test:test_support",
|
||||
"//testing/gtest",
|
||||
]
|
||||
}
|
||||
14
TMessagesProj/jni/voip/webrtc/api/neteq/DEPS
Normal file
14
TMessagesProj/jni/voip/webrtc/api/neteq/DEPS
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
specific_include_rules = {
|
||||
"custom_neteq_factory\.h": [
|
||||
"+system_wrappers/include/clock.h",
|
||||
],
|
||||
"default_neteq_factory\.h": [
|
||||
"+system_wrappers/include/clock.h",
|
||||
],
|
||||
"neteq_controller\.h": [
|
||||
"+system_wrappers/include/clock.h",
|
||||
],
|
||||
"neteq_factory\.h": [
|
||||
"+system_wrappers/include/clock.h",
|
||||
],
|
||||
}
|
||||
3
TMessagesProj/jni/voip/webrtc/api/neteq/OWNERS
Normal file
3
TMessagesProj/jni/voip/webrtc/api/neteq/OWNERS
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
ivoc@webrtc.org
|
||||
henrik.lundin@webrtc.org
|
||||
jakobi@webrtc.org
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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 "api/neteq/custom_neteq_factory.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "modules/audio_coding/neteq/neteq_impl.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
CustomNetEqFactory::CustomNetEqFactory(
|
||||
std::unique_ptr<NetEqControllerFactory> controller_factory)
|
||||
: controller_factory_(std::move(controller_factory)) {}
|
||||
|
||||
CustomNetEqFactory::~CustomNetEqFactory() = default;
|
||||
|
||||
std::unique_ptr<NetEq> CustomNetEqFactory::CreateNetEq(
|
||||
const NetEq::Config& config,
|
||||
const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory,
|
||||
Clock* clock) const {
|
||||
return std::make_unique<NetEqImpl>(
|
||||
config, NetEqImpl::Dependencies(config, clock, decoder_factory,
|
||||
*controller_factory_));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 API_NETEQ_CUSTOM_NETEQ_FACTORY_H_
|
||||
#define API_NETEQ_CUSTOM_NETEQ_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/audio_codecs/audio_decoder_factory.h"
|
||||
#include "api/neteq/neteq_controller_factory.h"
|
||||
#include "api/neteq/neteq_factory.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// This factory can be used to generate NetEq instances that make use of a
|
||||
// custom NetEqControllerFactory.
|
||||
class CustomNetEqFactory : public NetEqFactory {
|
||||
public:
|
||||
explicit CustomNetEqFactory(
|
||||
std::unique_ptr<NetEqControllerFactory> controller_factory);
|
||||
~CustomNetEqFactory() override;
|
||||
CustomNetEqFactory(const CustomNetEqFactory&) = delete;
|
||||
CustomNetEqFactory& operator=(const CustomNetEqFactory&) = delete;
|
||||
|
||||
std::unique_ptr<NetEq> CreateNetEq(
|
||||
const NetEq::Config& config,
|
||||
const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory,
|
||||
Clock* clock) const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<NetEqControllerFactory> controller_factory_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // API_NETEQ_CUSTOM_NETEQ_FACTORY_H_
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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 "api/neteq/default_neteq_controller_factory.h"
|
||||
|
||||
#include "modules/audio_coding/neteq/decision_logic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
DefaultNetEqControllerFactory::DefaultNetEqControllerFactory() = default;
|
||||
DefaultNetEqControllerFactory::~DefaultNetEqControllerFactory() = default;
|
||||
|
||||
std::unique_ptr<NetEqController>
|
||||
DefaultNetEqControllerFactory::CreateNetEqController(
|
||||
const NetEqController::Config& config) const {
|
||||
return std::make_unique<DecisionLogic>(config);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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 API_NETEQ_DEFAULT_NETEQ_CONTROLLER_FACTORY_H_
|
||||
#define API_NETEQ_DEFAULT_NETEQ_CONTROLLER_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/neteq/neteq_controller_factory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// This NetEqControllerFactory will use WebRTC's built-in controller logic.
|
||||
class DefaultNetEqControllerFactory : public NetEqControllerFactory {
|
||||
public:
|
||||
DefaultNetEqControllerFactory();
|
||||
~DefaultNetEqControllerFactory() override;
|
||||
DefaultNetEqControllerFactory(const DefaultNetEqControllerFactory&) = delete;
|
||||
DefaultNetEqControllerFactory& operator=(
|
||||
const DefaultNetEqControllerFactory&) = delete;
|
||||
|
||||
std::unique_ptr<NetEqController> CreateNetEqController(
|
||||
const NetEqController::Config& config) const override;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // API_NETEQ_DEFAULT_NETEQ_CONTROLLER_FACTORY_H_
|
||||
36
TMessagesProj/jni/voip/webrtc/api/neteq/neteq.cc
Normal file
36
TMessagesProj/jni/voip/webrtc/api/neteq/neteq.cc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2012 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 "api/neteq/neteq.h"
|
||||
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
NetEq::Config::Config() = default;
|
||||
NetEq::Config::Config(const Config&) = default;
|
||||
NetEq::Config::Config(Config&&) = default;
|
||||
NetEq::Config::~Config() = default;
|
||||
NetEq::Config& NetEq::Config::operator=(const Config&) = default;
|
||||
NetEq::Config& NetEq::Config::operator=(Config&&) = default;
|
||||
|
||||
std::string NetEq::Config::ToString() const {
|
||||
char buf[1024];
|
||||
rtc::SimpleStringBuilder ss(buf);
|
||||
ss << "sample_rate_hz=" << sample_rate_hz
|
||||
<< ", max_packets_in_buffer=" << max_packets_in_buffer
|
||||
<< ", min_delay_ms=" << min_delay_ms << ", enable_fast_accelerate="
|
||||
<< (enable_fast_accelerate ? "true" : "false")
|
||||
<< ", enable_muted_state=" << (enable_muted_state ? "true" : "false")
|
||||
<< ", enable_rtx_handling=" << (enable_rtx_handling ? "true" : "false");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
314
TMessagesProj/jni/voip/webrtc/api/neteq/neteq.h
Normal file
314
TMessagesProj/jni/voip/webrtc/api/neteq/neteq.h
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* Copyright (c) 2012 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 API_NETEQ_NETEQ_H_
|
||||
#define API_NETEQ_NETEQ_H_
|
||||
|
||||
#include <stddef.h> // Provide access to size_t.
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/rtp_headers.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Forward declarations.
|
||||
class AudioFrame;
|
||||
class AudioDecoderFactory;
|
||||
class Clock;
|
||||
|
||||
struct NetEqNetworkStatistics {
|
||||
uint16_t current_buffer_size_ms; // Current jitter buffer size in ms.
|
||||
uint16_t preferred_buffer_size_ms; // Target buffer size in ms.
|
||||
uint16_t jitter_peaks_found; // 1 if adding extra delay due to peaky
|
||||
// jitter; 0 otherwise.
|
||||
uint16_t expand_rate; // Fraction (of original stream) of synthesized
|
||||
// audio inserted through expansion (in Q14).
|
||||
uint16_t speech_expand_rate; // Fraction (of original stream) of synthesized
|
||||
// speech inserted through expansion (in Q14).
|
||||
uint16_t preemptive_rate; // Fraction of data inserted through pre-emptive
|
||||
// expansion (in Q14).
|
||||
uint16_t accelerate_rate; // Fraction of data removed through acceleration
|
||||
// (in Q14).
|
||||
uint16_t secondary_decoded_rate; // Fraction of data coming from FEC/RED
|
||||
// decoding (in Q14).
|
||||
uint16_t secondary_discarded_rate; // Fraction of discarded FEC/RED data (in
|
||||
// Q14).
|
||||
// Statistics for packet waiting times, i.e., the time between a packet
|
||||
// arrives until it is decoded.
|
||||
int mean_waiting_time_ms;
|
||||
int median_waiting_time_ms;
|
||||
int min_waiting_time_ms;
|
||||
int max_waiting_time_ms;
|
||||
};
|
||||
|
||||
// NetEq statistics that persist over the lifetime of the class.
|
||||
// These metrics are never reset.
|
||||
struct NetEqLifetimeStatistics {
|
||||
// Stats below correspond to similarly-named fields in the WebRTC stats spec.
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats
|
||||
uint64_t total_samples_received = 0;
|
||||
uint64_t concealed_samples = 0;
|
||||
uint64_t concealment_events = 0;
|
||||
uint64_t jitter_buffer_delay_ms = 0;
|
||||
uint64_t jitter_buffer_emitted_count = 0;
|
||||
uint64_t jitter_buffer_target_delay_ms = 0;
|
||||
uint64_t jitter_buffer_minimum_delay_ms = 0;
|
||||
uint64_t inserted_samples_for_deceleration = 0;
|
||||
uint64_t removed_samples_for_acceleration = 0;
|
||||
uint64_t silent_concealed_samples = 0;
|
||||
uint64_t fec_packets_received = 0;
|
||||
uint64_t fec_packets_discarded = 0;
|
||||
uint64_t packets_discarded = 0;
|
||||
// Below stats are not part of the spec.
|
||||
uint64_t delayed_packet_outage_samples = 0;
|
||||
uint64_t delayed_packet_outage_events = 0;
|
||||
// This is sum of relative packet arrival delays of received packets so far.
|
||||
// Since end-to-end delay of a packet is difficult to measure and is not
|
||||
// necessarily useful for measuring jitter buffer performance, we report a
|
||||
// relative packet arrival delay. The relative packet arrival delay of a
|
||||
// packet is defined as the arrival delay compared to the first packet
|
||||
// received, given that it had zero delay. To avoid clock drift, the "first"
|
||||
// packet can be made dynamic.
|
||||
uint64_t relative_packet_arrival_delay_ms = 0;
|
||||
uint64_t jitter_buffer_packets_received = 0;
|
||||
// An interruption is a loss-concealment event lasting at least 150 ms. The
|
||||
// two stats below count the number os such events and the total duration of
|
||||
// these events.
|
||||
int32_t interruption_count = 0;
|
||||
int32_t total_interruption_duration_ms = 0;
|
||||
// Total number of comfort noise samples generated during DTX.
|
||||
uint64_t generated_noise_samples = 0;
|
||||
};
|
||||
|
||||
// Metrics that describe the operations performed in NetEq, and the internal
|
||||
// state.
|
||||
struct NetEqOperationsAndState {
|
||||
// These sample counters are cumulative, and don't reset. As a reference, the
|
||||
// total number of output samples can be found in
|
||||
// NetEqLifetimeStatistics::total_samples_received.
|
||||
uint64_t preemptive_samples = 0;
|
||||
uint64_t accelerate_samples = 0;
|
||||
// Count of the number of buffer flushes.
|
||||
uint64_t packet_buffer_flushes = 0;
|
||||
// The statistics below are not cumulative.
|
||||
// The waiting time of the last decoded packet.
|
||||
uint64_t last_waiting_time_ms = 0;
|
||||
// The sum of the packet and jitter buffer size in ms.
|
||||
uint64_t current_buffer_size_ms = 0;
|
||||
// The current frame size in ms.
|
||||
uint64_t current_frame_size_ms = 0;
|
||||
// Flag to indicate that the next packet is available.
|
||||
bool next_packet_available = false;
|
||||
};
|
||||
|
||||
// This is the interface class for NetEq.
|
||||
class NetEq {
|
||||
public:
|
||||
struct Config {
|
||||
Config();
|
||||
Config(const Config&);
|
||||
Config(Config&&);
|
||||
~Config();
|
||||
Config& operator=(const Config&);
|
||||
Config& operator=(Config&&);
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
int sample_rate_hz = 48000; // Initial value. Will change with input data.
|
||||
size_t max_packets_in_buffer = 200;
|
||||
int max_delay_ms = 0;
|
||||
int min_delay_ms = 0;
|
||||
bool enable_fast_accelerate = false;
|
||||
bool enable_muted_state = false;
|
||||
bool enable_rtx_handling = false;
|
||||
absl::optional<AudioCodecPairId> codec_pair_id;
|
||||
bool for_test_no_time_stretching = false; // Use only for testing.
|
||||
};
|
||||
|
||||
enum ReturnCodes { kOK = 0, kFail = -1 };
|
||||
|
||||
enum class Operation {
|
||||
kNormal,
|
||||
kMerge,
|
||||
kExpand,
|
||||
kAccelerate,
|
||||
kFastAccelerate,
|
||||
kPreemptiveExpand,
|
||||
kRfc3389Cng,
|
||||
kRfc3389CngNoPacket,
|
||||
kCodecInternalCng,
|
||||
kDtmf,
|
||||
kUndefined,
|
||||
};
|
||||
|
||||
enum class Mode {
|
||||
kNormal,
|
||||
kExpand,
|
||||
kMerge,
|
||||
kAccelerateSuccess,
|
||||
kAccelerateLowEnergy,
|
||||
kAccelerateFail,
|
||||
kPreemptiveExpandSuccess,
|
||||
kPreemptiveExpandLowEnergy,
|
||||
kPreemptiveExpandFail,
|
||||
kRfc3389Cng,
|
||||
kCodecInternalCng,
|
||||
kCodecPlc,
|
||||
kDtmf,
|
||||
kError,
|
||||
kUndefined,
|
||||
};
|
||||
|
||||
// Return type for GetDecoderFormat.
|
||||
struct DecoderFormat {
|
||||
int sample_rate_hz;
|
||||
int num_channels;
|
||||
SdpAudioFormat sdp_format;
|
||||
};
|
||||
|
||||
virtual ~NetEq() {}
|
||||
|
||||
// Inserts a new packet into NetEq.
|
||||
// Returns 0 on success, -1 on failure.
|
||||
virtual int InsertPacket(const RTPHeader& rtp_header,
|
||||
rtc::ArrayView<const uint8_t> payload) = 0;
|
||||
|
||||
// Lets NetEq know that a packet arrived with an empty payload. This typically
|
||||
// happens when empty packets are used for probing the network channel, and
|
||||
// these packets use RTP sequence numbers from the same series as the actual
|
||||
// audio packets.
|
||||
virtual void InsertEmptyPacket(const RTPHeader& rtp_header) = 0;
|
||||
|
||||
// Instructs NetEq to deliver 10 ms of audio data. The data is written to
|
||||
// `audio_frame`. All data in `audio_frame` is wiped; `data_`, `speech_type_`,
|
||||
// `num_channels_`, `sample_rate_hz_` and `samples_per_channel_` are updated
|
||||
// upon success. If an error is returned, some fields may not have been
|
||||
// updated, or may contain inconsistent values. If muted state is enabled
|
||||
// (through Config::enable_muted_state), `muted` may be set to true after a
|
||||
// prolonged expand period. When this happens, the `data_` in `audio_frame`
|
||||
// is not written, but should be interpreted as being all zeros. For testing
|
||||
// purposes, an override can be supplied in the `action_override` argument,
|
||||
// which will cause NetEq to take this action next, instead of the action it
|
||||
// would normally choose. An optional output argument for fetching the current
|
||||
// sample rate can be provided, which will return the same value as
|
||||
// last_output_sample_rate_hz() but will avoid additional synchronization.
|
||||
// Returns kOK on success, or kFail in case of an error.
|
||||
virtual int GetAudio(
|
||||
AudioFrame* audio_frame,
|
||||
bool* muted,
|
||||
int* current_sample_rate_hz = nullptr,
|
||||
absl::optional<Operation> action_override = absl::nullopt) = 0;
|
||||
|
||||
// Replaces the current set of decoders with the given one.
|
||||
virtual void SetCodecs(const std::map<int, SdpAudioFormat>& codecs) = 0;
|
||||
|
||||
// Associates `rtp_payload_type` with the given codec, which NetEq will
|
||||
// instantiate when it needs it. Returns true iff successful.
|
||||
virtual bool RegisterPayloadType(int rtp_payload_type,
|
||||
const SdpAudioFormat& audio_format) = 0;
|
||||
|
||||
// Removes `rtp_payload_type` from the codec database. Returns 0 on success,
|
||||
// -1 on failure. Removing a payload type that is not registered is ok and
|
||||
// will not result in an error.
|
||||
virtual int RemovePayloadType(uint8_t rtp_payload_type) = 0;
|
||||
|
||||
// Removes all payload types from the codec database.
|
||||
virtual void RemoveAllPayloadTypes() = 0;
|
||||
|
||||
// Sets a minimum delay in millisecond for packet buffer. The minimum is
|
||||
// maintained unless a higher latency is dictated by channel condition.
|
||||
// Returns true if the minimum is successfully applied, otherwise false is
|
||||
// returned.
|
||||
virtual bool SetMinimumDelay(int delay_ms) = 0;
|
||||
|
||||
// Sets a maximum delay in milliseconds for packet buffer. The latency will
|
||||
// not exceed the given value, even required delay (given the channel
|
||||
// conditions) is higher. Calling this method has the same effect as setting
|
||||
// the `max_delay_ms` value in the NetEq::Config struct.
|
||||
virtual bool SetMaximumDelay(int delay_ms) = 0;
|
||||
|
||||
// Sets a base minimum delay in milliseconds for packet buffer. The minimum
|
||||
// delay which is set via `SetMinimumDelay` can't be lower than base minimum
|
||||
// delay. Calling this method is similar to setting the `min_delay_ms` value
|
||||
// in the NetEq::Config struct. Returns true if the base minimum is
|
||||
// successfully applied, otherwise false is returned.
|
||||
virtual bool SetBaseMinimumDelayMs(int delay_ms) = 0;
|
||||
|
||||
// Returns current value of base minimum delay in milliseconds.
|
||||
virtual int GetBaseMinimumDelayMs() const = 0;
|
||||
|
||||
// Returns the current target delay in ms. This includes any extra delay
|
||||
// requested through SetMinimumDelay.
|
||||
virtual int TargetDelayMs() const = 0;
|
||||
|
||||
// Returns the current total delay (packet buffer and sync buffer) in ms,
|
||||
// with smoothing applied to even out short-time fluctuations due to jitter.
|
||||
// The packet buffer part of the delay is not updated during DTX/CNG periods.
|
||||
virtual int FilteredCurrentDelayMs() const = 0;
|
||||
|
||||
// Writes the current network statistics to `stats`. The statistics are reset
|
||||
// after the call.
|
||||
virtual int NetworkStatistics(NetEqNetworkStatistics* stats) = 0;
|
||||
|
||||
// Current values only, not resetting any state.
|
||||
virtual NetEqNetworkStatistics CurrentNetworkStatistics() const = 0;
|
||||
|
||||
// Returns a copy of this class's lifetime statistics. These statistics are
|
||||
// never reset.
|
||||
virtual NetEqLifetimeStatistics GetLifetimeStatistics() const = 0;
|
||||
|
||||
// Returns statistics about the performed operations and internal state. These
|
||||
// statistics are never reset.
|
||||
virtual NetEqOperationsAndState GetOperationsAndState() const = 0;
|
||||
|
||||
// Returns the RTP timestamp for the last sample delivered by GetAudio().
|
||||
// The return value will be empty if no valid timestamp is available.
|
||||
virtual absl::optional<uint32_t> GetPlayoutTimestamp() const = 0;
|
||||
|
||||
// Returns the sample rate in Hz of the audio produced in the last GetAudio
|
||||
// call. If GetAudio has not been called yet, the configured sample rate
|
||||
// (Config::sample_rate_hz) is returned.
|
||||
virtual int last_output_sample_rate_hz() const = 0;
|
||||
|
||||
// Returns the decoder info for the given payload type. Returns empty if no
|
||||
// such payload type was registered.
|
||||
virtual absl::optional<DecoderFormat> GetDecoderFormat(
|
||||
int payload_type) const = 0;
|
||||
|
||||
// Flushes both the packet buffer and the sync buffer.
|
||||
virtual void FlushBuffers() = 0;
|
||||
|
||||
// Enables NACK and sets the maximum size of the NACK list, which should be
|
||||
// positive and no larger than Nack::kNackListSizeLimit. If NACK is already
|
||||
// enabled then the maximum NACK list size is modified accordingly.
|
||||
virtual void EnableNack(size_t max_nack_list_size) = 0;
|
||||
|
||||
virtual void DisableNack() = 0;
|
||||
|
||||
// Returns a list of RTP sequence numbers corresponding to packets to be
|
||||
// retransmitted, given an estimate of the round-trip time in milliseconds.
|
||||
virtual std::vector<uint16_t> GetNackList(
|
||||
int64_t round_trip_time_ms) const = 0;
|
||||
|
||||
// Returns the length of the audio yet to play in the sync buffer.
|
||||
// Mainly intended for testing.
|
||||
virtual int SyncBufferSizeMs() const = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // API_NETEQ_NETEQ_H_
|
||||
189
TMessagesProj/jni/voip/webrtc/api/neteq/neteq_controller.h
Normal file
189
TMessagesProj/jni/voip/webrtc/api/neteq/neteq_controller.h
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* 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 API_NETEQ_NETEQ_CONTROLLER_H_
|
||||
#define API_NETEQ_NETEQ_CONTROLLER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/neteq/neteq.h"
|
||||
#include "api/neteq/tick_timer.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Decides the actions that NetEq should take. This affects the behavior of the
|
||||
// jitter buffer, and how it reacts to network conditions.
|
||||
// This class will undergo substantial refactoring in the near future, and the
|
||||
// API is expected to undergo significant changes. A target API is given below:
|
||||
//
|
||||
// class NetEqController {
|
||||
// public:
|
||||
// // Resets object to a clean state.
|
||||
// void Reset();
|
||||
// // Given NetEq status, make a decision.
|
||||
// Operation GetDecision(NetEqStatus neteq_status);
|
||||
// // Register every packet received.
|
||||
// void RegisterPacket(PacketInfo packet_info);
|
||||
// // Register empty packet.
|
||||
// void RegisterEmptyPacket();
|
||||
// // Register a codec switching.
|
||||
// void CodecSwithed();
|
||||
// // Sets the sample rate.
|
||||
// void SetSampleRate(int fs_hz);
|
||||
// // Sets the packet length in samples.
|
||||
// void SetPacketLengthSamples();
|
||||
// // Sets maximum delay.
|
||||
// void SetMaximumDelay(int delay_ms);
|
||||
// // Sets mininum delay.
|
||||
// void SetMinimumDelay(int delay_ms);
|
||||
// // Sets base mininum delay.
|
||||
// void SetBaseMinimumDelay(int delay_ms);
|
||||
// // Gets target buffer level.
|
||||
// int GetTargetBufferLevelMs() const;
|
||||
// // Gets filtered buffer level.
|
||||
// int GetFilteredBufferLevel() const;
|
||||
// // Gets base minimum delay.
|
||||
// int GetBaseMinimumDelay() const;
|
||||
// }
|
||||
|
||||
class NetEqController {
|
||||
public:
|
||||
// This struct is used to create a NetEqController.
|
||||
struct Config {
|
||||
bool allow_time_stretching;
|
||||
bool enable_rtx_handling;
|
||||
int max_packets_in_buffer;
|
||||
int base_min_delay_ms;
|
||||
TickTimer* tick_timer;
|
||||
webrtc::Clock* clock = nullptr;
|
||||
};
|
||||
|
||||
struct PacketInfo {
|
||||
uint32_t timestamp;
|
||||
bool is_dtx;
|
||||
bool is_cng;
|
||||
};
|
||||
|
||||
struct PacketBufferInfo {
|
||||
bool dtx_or_cng;
|
||||
size_t num_samples;
|
||||
size_t span_samples;
|
||||
size_t span_samples_wait_time;
|
||||
size_t num_packets;
|
||||
};
|
||||
|
||||
struct NetEqStatus {
|
||||
uint32_t target_timestamp;
|
||||
int16_t expand_mutefactor;
|
||||
size_t last_packet_samples;
|
||||
absl::optional<PacketInfo> next_packet;
|
||||
NetEq::Mode last_mode;
|
||||
bool play_dtmf;
|
||||
size_t generated_noise_samples;
|
||||
PacketBufferInfo packet_buffer_info;
|
||||
size_t sync_buffer_samples;
|
||||
};
|
||||
|
||||
struct PacketArrivedInfo {
|
||||
size_t packet_length_samples;
|
||||
uint32_t main_timestamp;
|
||||
uint16_t main_sequence_number;
|
||||
bool is_cng_or_dtmf;
|
||||
bool is_dtx;
|
||||
bool buffer_flush;
|
||||
};
|
||||
|
||||
virtual ~NetEqController() = default;
|
||||
|
||||
// Resets object to a clean state.
|
||||
virtual void Reset() = 0;
|
||||
|
||||
// Resets parts of the state. Typically done when switching codecs.
|
||||
virtual void SoftReset() = 0;
|
||||
|
||||
// Given info about the latest received packet, and current jitter buffer
|
||||
// status, returns the operation. `target_timestamp` and `expand_mutefactor`
|
||||
// are provided for reference. `last_packet_samples` is the number of samples
|
||||
// obtained from the last decoded frame. If there is a packet available, it
|
||||
// should be supplied in `packet`. The mode resulting from the last call to
|
||||
// NetEqImpl::GetAudio is supplied in `last_mode`. If there is a DTMF event to
|
||||
// play, `play_dtmf` should be set to true. The output variable
|
||||
// `reset_decoder` will be set to true if a reset is required; otherwise it is
|
||||
// left unchanged (i.e., it can remain true if it was true before the call).
|
||||
virtual NetEq::Operation GetDecision(const NetEqStatus& status,
|
||||
bool* reset_decoder) = 0;
|
||||
|
||||
// Inform NetEqController that an empty packet has arrived.
|
||||
virtual void RegisterEmptyPacket() = 0;
|
||||
|
||||
// Sets the sample rate and the output block size.
|
||||
virtual void SetSampleRate(int fs_hz, size_t output_size_samples) = 0;
|
||||
|
||||
// Sets a minimum or maximum delay in millisecond.
|
||||
// Returns true if the delay bound is successfully applied, otherwise false.
|
||||
virtual bool SetMaximumDelay(int delay_ms) = 0;
|
||||
virtual bool SetMinimumDelay(int delay_ms) = 0;
|
||||
|
||||
// Sets a base minimum delay in milliseconds for packet buffer. The effective
|
||||
// minimum delay can't be lower than base minimum delay, even if a lower value
|
||||
// is set using SetMinimumDelay.
|
||||
// Returns true if the base minimum is successfully applied, otherwise false.
|
||||
virtual bool SetBaseMinimumDelay(int delay_ms) = 0;
|
||||
virtual int GetBaseMinimumDelay() const = 0;
|
||||
|
||||
// Reports back to DecisionLogic whether the decision to do expand remains or
|
||||
// not. Note that this is necessary, since an expand decision can be changed
|
||||
// to kNormal in NetEqImpl::GetDecision if there is still enough data in the
|
||||
// sync buffer.
|
||||
virtual void ExpandDecision(NetEq::Operation operation) = 0;
|
||||
|
||||
// Adds `value` to `sample_memory_`.
|
||||
virtual void AddSampleMemory(int32_t value) = 0;
|
||||
|
||||
// Returns the target buffer level in ms.
|
||||
virtual int TargetLevelMs() const = 0;
|
||||
|
||||
// Returns the target buffer level in ms as it would be if no minimum or
|
||||
// maximum delay was set.
|
||||
// TODO(bugs.webrtc.org/14270): Make pure virtual once all implementations are
|
||||
// updated.
|
||||
virtual int UnlimitedTargetLevelMs() const { return 0; }
|
||||
|
||||
// Notify the NetEqController that a packet has arrived. Returns the relative
|
||||
// arrival delay, if it can be computed.
|
||||
virtual absl::optional<int> PacketArrived(int fs_hz,
|
||||
bool should_update_stats,
|
||||
const PacketArrivedInfo& info) = 0;
|
||||
|
||||
// Notify the NetEqController that we are currently in muted state.
|
||||
// TODO(bugs.webrtc.org/14270): Make pure virtual when downstream is updated.
|
||||
virtual void NotifyMutedState() {}
|
||||
|
||||
// Returns true if a peak was found.
|
||||
virtual bool PeakFound() const = 0;
|
||||
|
||||
// Get the filtered buffer level in samples.
|
||||
virtual int GetFilteredBufferLevel() const = 0;
|
||||
|
||||
// Accessors and mutators.
|
||||
virtual void set_sample_memory(int32_t value) = 0;
|
||||
virtual size_t noise_fast_forward() const = 0;
|
||||
virtual size_t packet_length_samples() const = 0;
|
||||
virtual void set_packet_length_samples(size_t value) = 0;
|
||||
virtual void set_prev_time_scale(bool value) = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // API_NETEQ_NETEQ_CONTROLLER_H_
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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 API_NETEQ_NETEQ_CONTROLLER_FACTORY_H_
|
||||
#define API_NETEQ_NETEQ_CONTROLLER_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/neteq/neteq_controller.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Creates NetEqController instances using the settings provided in the config
|
||||
// struct.
|
||||
class NetEqControllerFactory {
|
||||
public:
|
||||
virtual ~NetEqControllerFactory() = default;
|
||||
|
||||
// Creates a new NetEqController object, with parameters set in `config`.
|
||||
virtual std::unique_ptr<NetEqController> CreateNetEqController(
|
||||
const NetEqController::Config& config) const = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // API_NETEQ_NETEQ_CONTROLLER_FACTORY_H_
|
||||
37
TMessagesProj/jni/voip/webrtc/api/neteq/neteq_factory.h
Normal file
37
TMessagesProj/jni/voip/webrtc/api/neteq/neteq_factory.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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 API_NETEQ_NETEQ_FACTORY_H_
|
||||
#define API_NETEQ_NETEQ_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/audio_codecs/audio_decoder_factory.h"
|
||||
#include "api/neteq/neteq.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Creates NetEq instances using the settings provided in the config struct.
|
||||
class NetEqFactory {
|
||||
public:
|
||||
virtual ~NetEqFactory() = default;
|
||||
|
||||
// Creates a new NetEq object, with parameters set in `config`. The `config`
|
||||
// object will only have to be valid for the duration of the call to this
|
||||
// method.
|
||||
virtual std::unique_ptr<NetEq> CreateNetEq(
|
||||
const NetEq::Config& config,
|
||||
const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory,
|
||||
Clock* clock) const = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // API_NETEQ_NETEQ_FACTORY_H_
|
||||
25
TMessagesProj/jni/voip/webrtc/api/neteq/tick_timer.cc
Normal file
25
TMessagesProj/jni/voip/webrtc/api/neteq/tick_timer.cc
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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 "api/neteq/tick_timer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
TickTimer::Stopwatch::Stopwatch(const TickTimer& ticktimer)
|
||||
: ticktimer_(ticktimer), starttick_(ticktimer.ticks()) {}
|
||||
|
||||
TickTimer::Countdown::Countdown(const TickTimer& ticktimer,
|
||||
uint64_t ticks_to_count)
|
||||
: stopwatch_(ticktimer.GetNewStopwatch()),
|
||||
ticks_to_count_(ticks_to_count) {}
|
||||
|
||||
TickTimer::Countdown::~Countdown() = default;
|
||||
|
||||
} // namespace webrtc
|
||||
112
TMessagesProj/jni/voip/webrtc/api/neteq/tick_timer.h
Normal file
112
TMessagesProj/jni/voip/webrtc/api/neteq/tick_timer.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef API_NETEQ_TICK_TIMER_H_
|
||||
#define API_NETEQ_TICK_TIMER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Implements a time counter. The counter is advanced with the Increment()
|
||||
// methods, and is queried with the ticks() accessor. It is assumed that one
|
||||
// "tick" of the counter corresponds to 10 ms.
|
||||
// A TickTimer object can provide two types of associated time-measuring
|
||||
// objects: Stopwatch and Countdown.
|
||||
class TickTimer {
|
||||
public:
|
||||
// Stopwatch measures time elapsed since it was started, by querying the
|
||||
// associated TickTimer for the current time. The intended use is to request a
|
||||
// new Stopwatch object from a TickTimer object with the GetNewStopwatch()
|
||||
// method. Note: since the Stopwatch object contains a reference to the
|
||||
// TickTimer it is associated with, it cannot outlive the TickTimer.
|
||||
class Stopwatch {
|
||||
public:
|
||||
explicit Stopwatch(const TickTimer& ticktimer);
|
||||
|
||||
uint64_t ElapsedTicks() const { return ticktimer_.ticks() - starttick_; }
|
||||
|
||||
uint64_t ElapsedMs() const {
|
||||
const uint64_t elapsed_ticks = ticktimer_.ticks() - starttick_;
|
||||
const int ms_per_tick = ticktimer_.ms_per_tick();
|
||||
return elapsed_ticks < UINT64_MAX / ms_per_tick
|
||||
? elapsed_ticks * ms_per_tick
|
||||
: UINT64_MAX;
|
||||
}
|
||||
|
||||
private:
|
||||
const TickTimer& ticktimer_;
|
||||
const uint64_t starttick_;
|
||||
};
|
||||
|
||||
// Countdown counts down from a given start value with each tick of the
|
||||
// associated TickTimer, until zero is reached. The Finished() method will
|
||||
// return true if zero has been reached, false otherwise. The intended use is
|
||||
// to request a new Countdown object from a TickTimer object with the
|
||||
// GetNewCountdown() method. Note: since the Countdown object contains a
|
||||
// reference to the TickTimer it is associated with, it cannot outlive the
|
||||
// TickTimer.
|
||||
class Countdown {
|
||||
public:
|
||||
Countdown(const TickTimer& ticktimer, uint64_t ticks_to_count);
|
||||
|
||||
~Countdown();
|
||||
|
||||
bool Finished() const {
|
||||
return stopwatch_->ElapsedTicks() >= ticks_to_count_;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Stopwatch> stopwatch_;
|
||||
const uint64_t ticks_to_count_;
|
||||
};
|
||||
|
||||
TickTimer() : TickTimer(10) {}
|
||||
explicit TickTimer(int ms_per_tick) : ms_per_tick_(ms_per_tick) {
|
||||
RTC_DCHECK_GT(ms_per_tick_, 0);
|
||||
}
|
||||
|
||||
TickTimer(const TickTimer&) = delete;
|
||||
TickTimer& operator=(const TickTimer&) = delete;
|
||||
|
||||
void Increment() { ++ticks_; }
|
||||
|
||||
// Mainly intended for testing.
|
||||
void Increment(uint64_t x) { ticks_ += x; }
|
||||
|
||||
uint64_t ticks() const { return ticks_; }
|
||||
|
||||
int ms_per_tick() const { return ms_per_tick_; }
|
||||
|
||||
// Returns a new Stopwatch object, based on the current TickTimer. Note that
|
||||
// the new Stopwatch object contains a reference to the current TickTimer,
|
||||
// and must therefore not outlive the TickTimer.
|
||||
std::unique_ptr<Stopwatch> GetNewStopwatch() const {
|
||||
return std::unique_ptr<Stopwatch>(new Stopwatch(*this));
|
||||
}
|
||||
|
||||
// Returns a new Countdown object, based on the current TickTimer. Note that
|
||||
// the new Countdown object contains a reference to the current TickTimer,
|
||||
// and must therefore not outlive the TickTimer.
|
||||
std::unique_ptr<Countdown> GetNewCountdown(uint64_t ticks_to_count) const {
|
||||
return std::unique_ptr<Countdown>(new Countdown(*this, ticks_to_count));
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t ticks_ = 0;
|
||||
const int ms_per_tick_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // API_NETEQ_TICK_TIMER_H_
|
||||
135
TMessagesProj/jni/voip/webrtc/api/neteq/tick_timer_unittest.cc
Normal file
135
TMessagesProj/jni/voip/webrtc/api/neteq/tick_timer_unittest.cc
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* 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 "api/neteq/tick_timer.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Verify that the default value for ms_per_tick is 10.
|
||||
TEST(TickTimer, DefaultMsPerTick) {
|
||||
TickTimer tt;
|
||||
EXPECT_EQ(10, tt.ms_per_tick());
|
||||
}
|
||||
|
||||
TEST(TickTimer, CustomMsPerTick) {
|
||||
TickTimer tt(17);
|
||||
EXPECT_EQ(17, tt.ms_per_tick());
|
||||
}
|
||||
|
||||
TEST(TickTimer, Increment) {
|
||||
TickTimer tt;
|
||||
EXPECT_EQ(0u, tt.ticks());
|
||||
tt.Increment();
|
||||
EXPECT_EQ(1u, tt.ticks());
|
||||
|
||||
for (int i = 0; i < 17; ++i) {
|
||||
tt.Increment();
|
||||
}
|
||||
EXPECT_EQ(18u, tt.ticks());
|
||||
|
||||
tt.Increment(17);
|
||||
EXPECT_EQ(35u, tt.ticks());
|
||||
}
|
||||
|
||||
TEST(TickTimer, WrapAround) {
|
||||
TickTimer tt;
|
||||
tt.Increment(UINT64_MAX);
|
||||
EXPECT_EQ(UINT64_MAX, tt.ticks());
|
||||
tt.Increment();
|
||||
EXPECT_EQ(0u, tt.ticks());
|
||||
}
|
||||
|
||||
TEST(TickTimer, Stopwatch) {
|
||||
TickTimer tt;
|
||||
// Increment it a "random" number of steps.
|
||||
tt.Increment(17);
|
||||
|
||||
std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
|
||||
ASSERT_TRUE(sw);
|
||||
|
||||
EXPECT_EQ(0u, sw->ElapsedTicks()); // Starts at zero.
|
||||
EXPECT_EQ(0u, sw->ElapsedMs());
|
||||
tt.Increment();
|
||||
EXPECT_EQ(1u, sw->ElapsedTicks()); // Increases with the TickTimer.
|
||||
EXPECT_EQ(10u, sw->ElapsedMs());
|
||||
}
|
||||
|
||||
TEST(TickTimer, StopwatchWrapAround) {
|
||||
TickTimer tt;
|
||||
tt.Increment(UINT64_MAX);
|
||||
|
||||
std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
|
||||
ASSERT_TRUE(sw);
|
||||
|
||||
tt.Increment();
|
||||
EXPECT_EQ(0u, tt.ticks());
|
||||
EXPECT_EQ(1u, sw->ElapsedTicks());
|
||||
EXPECT_EQ(10u, sw->ElapsedMs());
|
||||
|
||||
tt.Increment();
|
||||
EXPECT_EQ(1u, tt.ticks());
|
||||
EXPECT_EQ(2u, sw->ElapsedTicks());
|
||||
EXPECT_EQ(20u, sw->ElapsedMs());
|
||||
}
|
||||
|
||||
TEST(TickTimer, StopwatchMsOverflow) {
|
||||
TickTimer tt;
|
||||
std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
|
||||
ASSERT_TRUE(sw);
|
||||
|
||||
tt.Increment(UINT64_MAX / 10);
|
||||
EXPECT_EQ(UINT64_MAX, sw->ElapsedMs());
|
||||
|
||||
tt.Increment();
|
||||
EXPECT_EQ(UINT64_MAX, sw->ElapsedMs());
|
||||
|
||||
tt.Increment(UINT64_MAX - tt.ticks());
|
||||
EXPECT_EQ(UINT64_MAX, tt.ticks());
|
||||
EXPECT_EQ(UINT64_MAX, sw->ElapsedMs());
|
||||
}
|
||||
|
||||
TEST(TickTimer, StopwatchWithCustomTicktime) {
|
||||
const int kMsPerTick = 17;
|
||||
TickTimer tt(kMsPerTick);
|
||||
std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
|
||||
ASSERT_TRUE(sw);
|
||||
|
||||
EXPECT_EQ(0u, sw->ElapsedMs());
|
||||
tt.Increment();
|
||||
EXPECT_EQ(static_cast<uint64_t>(kMsPerTick), sw->ElapsedMs());
|
||||
}
|
||||
|
||||
TEST(TickTimer, Countdown) {
|
||||
TickTimer tt;
|
||||
// Increment it a "random" number of steps.
|
||||
tt.Increment(4711);
|
||||
|
||||
std::unique_ptr<TickTimer::Countdown> cd = tt.GetNewCountdown(17);
|
||||
ASSERT_TRUE(cd);
|
||||
|
||||
EXPECT_FALSE(cd->Finished());
|
||||
tt.Increment();
|
||||
EXPECT_FALSE(cd->Finished());
|
||||
|
||||
tt.Increment(16); // Total increment is now 17.
|
||||
EXPECT_TRUE(cd->Finished());
|
||||
|
||||
// Further increments do not change the state.
|
||||
tt.Increment();
|
||||
EXPECT_TRUE(cd->Finished());
|
||||
tt.Increment(1234);
|
||||
EXPECT_TRUE(cd->Finished());
|
||||
}
|
||||
} // namespace webrtc
|
||||
Loading…
Add table
Add a link
Reference in a new issue