Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
latency_monitor.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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_monitor.h
10 //! @brief Latency monitor.
11 
12 #ifndef ROC_AUDIO_LATENCY_MONITOR_H_
13 #define ROC_AUDIO_LATENCY_MONITOR_H_
14 
15 #include "roc_audio/depacketizer.h"
20 #include "roc_audio/sample_spec.h"
21 #include "roc_core/attributes.h"
22 #include "roc_core/noncopyable.h"
23 #include "roc_core/optional.h"
24 #include "roc_core/time.h"
25 #include "roc_packet/ilink_meter.h"
27 #include "roc_packet/units.h"
28 
29 namespace roc {
30 namespace audio {
31 
32 //! Latency monitor.
33 //!
34 //! @b Features
35 //!
36 //! - calculates NIQ latency (network incoming queue) - how many samples are
37 //! buffered in receiver packet queue and receiver pipeline before depacketizer
38 //! - calculates E2E latency (end-to-end) - how much time passed between frame
39 //! was captured on sender and played on receiver (this is based on capture
40 //! timestamps, which are populated with the help of RTCP)
41 //! - asks LatencyTuner to calculate scaling factor based on the actual and
42 //! target latencies
43 //! - passes calculated scaling factor to resampler
44 //!
45 //! @b Flow
46 //!
47 //! - pipeline periodically calls read() method; it uses references to incoming
48 //! packet queue (start of the pipeline) and depacketizer (last pipeline element
49 //! that works with packets), asks them about current packet / frame, and calculates
50 //! distance between them, which is NIQ latency
51 //! - after adding frame to playback buffer, pipeline invokes reclock() method;
52 //! it calculates difference between capture and playback time of the frame,
53 //! which is E2E latency
54 //! - latency monitor has an instance of LatencyTuner; it continuously passes
55 //! calculated latencies to it, and obtains scaling factor for resampler
56 //! - latency monitor has a reference to resampler, and periodically passes
57 //! updated scaling factor to it
58 //! - pipeline also can query latency monitor for latency metrics on behalf of
59 //! request from user or to report them to sender via RTCP
60 class LatencyMonitor : public IFrameReader, public core::NonCopyable<> {
61 public:
62  //! Constructor.
64  const packet::SortedQueue& incoming_queue,
65  const Depacketizer& depacketizer,
66  const packet::ILinkMeter& link_meter,
67  ResamplerReader* resampler,
68  const LatencyConfig& config,
69  const SampleSpec& packet_sample_spec,
70  const SampleSpec& frame_sample_spec);
71 
72  //! Check if the object was initialized successfully.
73  bool is_valid() const;
74 
75  //! Check if the stream is still alive.
76  bool is_alive() const;
77 
78  //! Get metrics.
79  const LatencyMetrics& metrics() const;
80 
81  //! Read audio frame from a pipeline.
82  //! @remarks
83  //! Forwards frame from underlying reader as-is.
84  virtual bool read(Frame& frame);
85 
86  //! Report playback timestamp of last frame returned by read.
87  //! @remarks
88  //! Pipeline invokes this method after adding last frame to
89  //! playback buffer and knowing its playback time.
90  //! @returns
91  //! false if the session is ended
92  bool reclock(core::nanoseconds_t playback_timestamp);
93 
94 private:
95  void compute_niq_latency_();
96  void compute_e2e_latency_(core::nanoseconds_t playback_timestamp);
97  void query_link_meter_();
98 
99  bool pre_process_(const Frame& frame);
100  void post_process_(const Frame& frame);
101 
102  bool init_scaling_();
103  bool update_scaling_();
104 
105  LatencyTuner tuner_;
106 
107  LatencyMetrics latency_metrics_;
108  packet::LinkMetrics link_metrics_;
109 
110  IFrameReader& frame_reader_;
111 
112  const packet::SortedQueue& incoming_queue_;
113  const Depacketizer& depacketizer_;
114  const packet::ILinkMeter& link_meter_;
115 
116  ResamplerReader* resampler_;
117  const bool enable_scaling_;
118 
119  core::nanoseconds_t capture_ts_;
120 
121  const SampleSpec packet_sample_spec_;
122  const SampleSpec frame_sample_spec_;
123 
124  bool alive_;
125  bool valid_;
126 };
127 
128 } // namespace audio
129 } // namespace roc
130 
131 #endif // ROC_AUDIO_LATENCY_MONITOR_H_
Compiler attributes.
Audio frame.
Definition: frame.h:25
Frame reader interface.
Definition: iframe_reader.h:22
bool reclock(core::nanoseconds_t playback_timestamp)
Report playback timestamp of last frame returned by read.
LatencyMonitor(IFrameReader &frame_reader, const packet::SortedQueue &incoming_queue, const Depacketizer &depacketizer, const packet::ILinkMeter &link_meter, ResamplerReader *resampler, const LatencyConfig &config, const SampleSpec &packet_sample_spec, const SampleSpec &frame_sample_spec)
Constructor.
virtual bool read(Frame &frame)
Read audio frame from a pipeline.
bool is_valid() const
Check if the object was initialized successfully.
const LatencyMetrics & metrics() const
Get metrics.
bool is_alive() const
Check if the stream is still alive.
Resampler element for reading pipeline.
Sample specification. Describes sample rate and channels.
Definition: sample_spec.h:30
Base class for non-copyable objects.
Definition: noncopyable.h:23
Link meter interface.
Definition: ilink_meter.h:71
Sorted packet queue.
Definition: sorted_queue.h:27
Depacketizer.
Frequency estimator.
Frame reader interface.
Latency tuner.
int64_t nanoseconds_t
Nanoseconds.
Definition: time.h:58
Root namespace.
Non-copyable object.
Optionally constructed object.
Sample specifications.
Sorted packet queue.
Latency settings.
Definition: latency_tuner.h:64
Latency-related metrics.
Time definitions.
Various units used in packets.