Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
Loading...
Searching...
No Matches
latency_tuner.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 Roc Streaming authors
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 */
8
9//! @file roc_audio/latency_tuner.h
10//! @brief Latency tuner.
11
12#ifndef ROC_AUDIO_LATENCY_TUNER_H_
13#define ROC_AUDIO_LATENCY_TUNER_H_
14
18#include "roc_core/optional.h"
19#include "roc_core/time.h"
21#include "roc_packet/units.h"
23
24namespace roc {
25namespace audio {
26
27//! Latency tuner backend.
28//! Defines which latency we monitor and tune to achieve target.
30 //! Deduce best default for given settings.
32
33 //! Latency is Network Incoming Queue length.
34 //! Calculated on receiver without use of any signaling protocol.
35 //! Reported back to sender via RTCP XR.
37
38 //! Latency is End-to-end delay.
39 //! Can on receiver if RTCP XR is supported by both sides.
40 //! Reported back to sender via RTCP XR.
42};
43
44//! Latency tuner profile.
45//! Defines whether and how we tune latency on fly to compensate clock
46//! drift and jitter.
48 //! Deduce best default for given settings.
50
51 //! Do not tune latency.
53
54 //! Fast and responsive tuning.
55 //! Good for lower network latency and jitter.
57
58 //! Slow and smooth tuning.
59 //! Good for higher network latency and jitter.
61};
62
63//! Latency settings.
65 //! Latency tuner backend to use.
66 //! @remarks
67 //! Defines which latency to monitor & tune.
69
70 //! Latency tuner profile to use.
71 //! @remarks
72 //! Defines how smooth is the tuning.
74
75 //! Target latency.
76 //! @remarks
77 //! Latency tuner will try to keep latency close to this value.
78 //! @note
79 //! If zero, default value is used if possible.
80 //! Negative value is an error.
82
83 //! Maximum allowed deviation from target latency.
84 //! @remarks
85 //! If the latency goes out of bounds, the session is terminated.
86 //! @note
87 //! If zero, default value is used if possible.
88 //! Negative value is an error.
90
91 //! Maximum delay since last packet before queue is considered stalling.
92 //! @remarks
93 //! If niq_stalling becomes larger than stalling_tolerance, latency
94 //! tolerance checks are temporary disabled.
95 //! @note
96 //! If zero, default value is used if possible.
97 //! Negative value is an error.
99
100 //! Scaling update interval.
101 //! @remarks
102 //! How often to run FreqEstimator and update Resampler scaling.
103 //! @note
104 //! If zero, default value is used.
105 //! Negative value is an error.
107
108 //! Maximum allowed deviation of freq_coeff from 1.0.
109 //! @remarks
110 //! If the scaling goes out of bounds, it is trimmed.
111 //! For example, 0.01 allows freq_coeff values in range [0.99; 1.01].
112 //! @note
113 //! If zero, default value is used.
114 //! Negative value is an error.
116
117 //! Initialize.
127
128 //! Automatically fill missing settings.
129 void deduce_defaults(core::nanoseconds_t default_target_latency, bool is_receiver);
130};
131
132//! Latency-related metrics.
134 //! Estimated network incoming queue latency.
135 //! An estimate of how much media is buffered in receiver packet queue.
137
138 //! Delay since last received packet.
139 //! In other words, how long there were no new packets in network incoming queue.
141
142 //! Estimated end-to-end latency.
143 //! An estimate of the time from recording a frame on sender to playing it
144 //! on receiver.
146
148 : niq_latency(0)
149 , niq_stalling(0)
150 , e2e_latency(0) {
151 }
152};
153
154//! Latency tuner.
155//!
156//! On receiver, LatencyMonitor computes local metrics and passes them to LatencyTuner.
157//! On sender, FeedbackMonitor obtains remote metrics and passes them to LatencyTuner.
158//! In both cases, LatencyTuner processes metrics and computes scaling factor that
159//! should be passed to resampler.
160//!
161//! Features:
162//! - monitors how close actual latency and target latency are
163//! - monitors whether latency goes out of bounds
164//! - assuming that the difference between actual latency and target latency is
165//! caused by the clock drift between sender and receiver, calculates scaling
166//! factor for resampler to compensate it
168public:
169 //! Initialize.
170 LatencyTuner(const LatencyConfig& config, const SampleSpec& sample_spec);
171
172 //! Check if the object was initialized successfully.
173 bool is_valid() const;
174
175 //! Pass updated metrics to tuner.
176 //! Tuner will use new values next time when update_stream() is called.
177 void write_metrics(const LatencyMetrics& latency_metrics,
178 const packet::LinkMetrics& link_metrics);
179
180 //! Update stream latency and scaling.
181 //! This method performs all actual work:
182 //! - depending on configured backend, selects which latency from
183 //! metrics to use
184 //! - check if latency goes out of bounds and session should be
185 //! terminated; if so, returns false
186 //! - computes updated scaling based on latency history and configured
187 //! profile
189
190 //! Advance stream by given number of samples.
191 //! Should be called after updating stream.
193
194 //! If scaling has changed, returns updated value.
195 //! Otherwise, returns zero.
196 //! @remarks
197 //! Latency tuner expects that this scaling will applied to the stream
198 //! resampler, so that the latency will slowly achieve target value.
199 //! Returned value is close to 1.0.
201
202private:
203 bool check_bounds_(packet::stream_timestamp_diff_t latency);
204 void compute_scaling_(packet::stream_timestamp_diff_t latency);
205 void report_();
206
208
209 packet::stream_timestamp_t stream_pos_;
210
211 packet::stream_timestamp_diff_t scale_interval_;
213
214 packet::stream_timestamp_diff_t report_interval_;
215 packet::stream_timestamp_t report_pos_;
216
217 bool has_new_freq_coeff_;
218 float freq_coeff_;
219 const float freq_coeff_max_delta_;
220
221 const LatencyTunerBackend backend_;
222 const LatencyTunerProfile profile_;
223
224 const bool enable_tuning_;
225 const bool enable_bounds_;
226
227 bool has_niq_latency_;
230
231 bool has_e2e_latency_;
233
234 bool has_jitter_;
236
237 packet::stream_timestamp_diff_t target_latency_;
241
242 const SampleSpec sample_spec_;
243
244 bool valid_;
245};
246
247//! Get string name of latency backend.
249
250//! Get string name of latency tuner.
252
253} // namespace audio
254} // namespace roc
255
256#endif // ROC_AUDIO_LATENCY_TUNER_H_
float fetch_scaling()
If scaling has changed, returns updated value. Otherwise, returns zero.
void advance_stream(packet::stream_timestamp_t duration)
Advance stream by given number of samples. Should be called after updating stream.
bool is_valid() const
Check if the object was initialized successfully.
bool update_stream()
Update stream latency and scaling. This method performs all actual work:
void write_metrics(const LatencyMetrics &latency_metrics, const packet::LinkMetrics &link_metrics)
Pass updated metrics to tuner. Tuner will use new values next time when update_stream() is called.
LatencyTuner(const LatencyConfig &config, const SampleSpec &sample_spec)
Initialize.
Sample specification. Describes sample rate and channels.
Definition sample_spec.h:30
Base class for non-copyable objects.
Definition noncopyable.h:23
Optionally constructed object.
Definition optional.h:25
Frequency estimator.
LatencyTunerBackend
Latency tuner backend. Defines which latency we monitor and tune to achieve target.
@ LatencyTunerBackend_Niq
Latency is Network Incoming Queue length. Calculated on receiver without use of any signaling protoco...
@ LatencyTunerBackend_E2e
Latency is End-to-end delay. Can on receiver if RTCP XR is supported by both sides....
@ LatencyTunerBackend_Default
Deduce best default for given settings.
const char * latency_tuner_backend_to_str(LatencyTunerBackend backend)
Get string name of latency backend.
LatencyTunerProfile
Latency tuner profile. Defines whether and how we tune latency on fly to compensate clock drift and j...
@ LatencyTunerProfile_Responsive
Fast and responsive tuning. Good for lower network latency and jitter.
@ LatencyTunerProfile_Default
Deduce best default for given settings.
@ LatencyTunerProfile_Gradual
Slow and smooth tuning. Good for higher network latency and jitter.
@ LatencyTunerProfile_Intact
Do not tune latency.
const char * latency_tuner_profile_to_str(LatencyTunerProfile tuner)
Get string name of latency tuner.
int64_t nanoseconds_t
Nanoseconds.
Definition time.h:58
uint32_t stream_timestamp_t
Packet stream timestamp.
Definition units.h:36
int32_t stream_timestamp_diff_t
Packet stream timestamp delta.
Definition units.h:41
Root namespace.
Non-copyable object.
Optionally constructed object.
Sample specifications.
Status codes.
core::nanoseconds_t target_latency
Target latency.
LatencyTunerProfile tuner_profile
Latency tuner profile to use.
core::nanoseconds_t latency_tolerance
Maximum allowed deviation from target latency.
void deduce_defaults(core::nanoseconds_t default_target_latency, bool is_receiver)
Automatically fill missing settings.
core::nanoseconds_t scaling_interval
Scaling update interval.
float scaling_tolerance
Maximum allowed deviation of freq_coeff from 1.0.
core::nanoseconds_t stale_tolerance
Maximum delay since last packet before queue is considered stalling.
LatencyTunerBackend tuner_backend
Latency tuner backend to use.
Latency-related metrics.
core::nanoseconds_t niq_latency
Estimated network incoming queue latency. An estimate of how much media is buffered in receiver packe...
core::nanoseconds_t e2e_latency
Estimated end-to-end latency. An estimate of the time from recording a frame on sender to playing it ...
core::nanoseconds_t niq_stalling
Delay since last received packet. In other words, how long there were no new packets in network incom...
Time definitions.
Various units used in packets.