xref: /aosp_15_r20/external/webrtc/api/neteq/neteq_controller.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef API_NETEQ_NETEQ_CONTROLLER_H_
12*d9f75844SAndroid Build Coastguard Worker #define API_NETEQ_NETEQ_CONTROLLER_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <cstddef>
15*d9f75844SAndroid Build Coastguard Worker #include <cstdint>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include <functional>
18*d9f75844SAndroid Build Coastguard Worker #include <memory>
19*d9f75844SAndroid Build Coastguard Worker 
20*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/neteq/neteq.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/neteq/tick_timer.h"
23*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h"
24*d9f75844SAndroid Build Coastguard Worker 
25*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
26*d9f75844SAndroid Build Coastguard Worker 
27*d9f75844SAndroid Build Coastguard Worker // Decides the actions that NetEq should take. This affects the behavior of the
28*d9f75844SAndroid Build Coastguard Worker // jitter buffer, and how it reacts to network conditions.
29*d9f75844SAndroid Build Coastguard Worker // This class will undergo substantial refactoring in the near future, and the
30*d9f75844SAndroid Build Coastguard Worker // API is expected to undergo significant changes. A target API is given below:
31*d9f75844SAndroid Build Coastguard Worker //
32*d9f75844SAndroid Build Coastguard Worker // class NetEqController {
33*d9f75844SAndroid Build Coastguard Worker //  public:
34*d9f75844SAndroid Build Coastguard Worker //   // Resets object to a clean state.
35*d9f75844SAndroid Build Coastguard Worker //   void Reset();
36*d9f75844SAndroid Build Coastguard Worker //   // Given NetEq status, make a decision.
37*d9f75844SAndroid Build Coastguard Worker //   Operation GetDecision(NetEqStatus neteq_status);
38*d9f75844SAndroid Build Coastguard Worker //   // Register every packet received.
39*d9f75844SAndroid Build Coastguard Worker //   void RegisterPacket(PacketInfo packet_info);
40*d9f75844SAndroid Build Coastguard Worker //   // Register empty packet.
41*d9f75844SAndroid Build Coastguard Worker //   void RegisterEmptyPacket();
42*d9f75844SAndroid Build Coastguard Worker //   // Register a codec switching.
43*d9f75844SAndroid Build Coastguard Worker //   void CodecSwithed();
44*d9f75844SAndroid Build Coastguard Worker //   // Sets the sample rate.
45*d9f75844SAndroid Build Coastguard Worker //   void SetSampleRate(int fs_hz);
46*d9f75844SAndroid Build Coastguard Worker //   // Sets the packet length in samples.
47*d9f75844SAndroid Build Coastguard Worker //   void SetPacketLengthSamples();
48*d9f75844SAndroid Build Coastguard Worker //   // Sets maximum delay.
49*d9f75844SAndroid Build Coastguard Worker //   void SetMaximumDelay(int delay_ms);
50*d9f75844SAndroid Build Coastguard Worker //   // Sets mininum delay.
51*d9f75844SAndroid Build Coastguard Worker //   void SetMinimumDelay(int delay_ms);
52*d9f75844SAndroid Build Coastguard Worker //   // Sets base mininum delay.
53*d9f75844SAndroid Build Coastguard Worker //   void SetBaseMinimumDelay(int delay_ms);
54*d9f75844SAndroid Build Coastguard Worker //   // Gets target buffer level.
55*d9f75844SAndroid Build Coastguard Worker //   int GetTargetBufferLevelMs() const;
56*d9f75844SAndroid Build Coastguard Worker //   // Gets filtered buffer level.
57*d9f75844SAndroid Build Coastguard Worker //   int GetFilteredBufferLevel() const;
58*d9f75844SAndroid Build Coastguard Worker //   // Gets base minimum delay.
59*d9f75844SAndroid Build Coastguard Worker //   int GetBaseMinimumDelay() const;
60*d9f75844SAndroid Build Coastguard Worker // }
61*d9f75844SAndroid Build Coastguard Worker 
62*d9f75844SAndroid Build Coastguard Worker class NetEqController {
63*d9f75844SAndroid Build Coastguard Worker  public:
64*d9f75844SAndroid Build Coastguard Worker   // This struct is used to create a NetEqController.
65*d9f75844SAndroid Build Coastguard Worker   struct Config {
66*d9f75844SAndroid Build Coastguard Worker     bool allow_time_stretching;
67*d9f75844SAndroid Build Coastguard Worker     bool enable_rtx_handling;
68*d9f75844SAndroid Build Coastguard Worker     int max_packets_in_buffer;
69*d9f75844SAndroid Build Coastguard Worker     int base_min_delay_ms;
70*d9f75844SAndroid Build Coastguard Worker     TickTimer* tick_timer;
71*d9f75844SAndroid Build Coastguard Worker     webrtc::Clock* clock = nullptr;
72*d9f75844SAndroid Build Coastguard Worker   };
73*d9f75844SAndroid Build Coastguard Worker 
74*d9f75844SAndroid Build Coastguard Worker   struct PacketInfo {
75*d9f75844SAndroid Build Coastguard Worker     uint32_t timestamp;
76*d9f75844SAndroid Build Coastguard Worker     bool is_dtx;
77*d9f75844SAndroid Build Coastguard Worker     bool is_cng;
78*d9f75844SAndroid Build Coastguard Worker   };
79*d9f75844SAndroid Build Coastguard Worker 
80*d9f75844SAndroid Build Coastguard Worker   struct PacketBufferInfo {
81*d9f75844SAndroid Build Coastguard Worker     bool dtx_or_cng;
82*d9f75844SAndroid Build Coastguard Worker     size_t num_samples;
83*d9f75844SAndroid Build Coastguard Worker     size_t span_samples;
84*d9f75844SAndroid Build Coastguard Worker     size_t span_samples_no_dtx;
85*d9f75844SAndroid Build Coastguard Worker     size_t num_packets;
86*d9f75844SAndroid Build Coastguard Worker   };
87*d9f75844SAndroid Build Coastguard Worker 
88*d9f75844SAndroid Build Coastguard Worker   struct NetEqStatus {
89*d9f75844SAndroid Build Coastguard Worker     uint32_t target_timestamp;
90*d9f75844SAndroid Build Coastguard Worker     int16_t expand_mutefactor;
91*d9f75844SAndroid Build Coastguard Worker     size_t last_packet_samples;
92*d9f75844SAndroid Build Coastguard Worker     absl::optional<PacketInfo> next_packet;
93*d9f75844SAndroid Build Coastguard Worker     NetEq::Mode last_mode;
94*d9f75844SAndroid Build Coastguard Worker     bool play_dtmf;
95*d9f75844SAndroid Build Coastguard Worker     size_t generated_noise_samples;
96*d9f75844SAndroid Build Coastguard Worker     PacketBufferInfo packet_buffer_info;
97*d9f75844SAndroid Build Coastguard Worker     size_t sync_buffer_samples;
98*d9f75844SAndroid Build Coastguard Worker   };
99*d9f75844SAndroid Build Coastguard Worker 
100*d9f75844SAndroid Build Coastguard Worker   struct PacketArrivedInfo {
101*d9f75844SAndroid Build Coastguard Worker     size_t packet_length_samples;
102*d9f75844SAndroid Build Coastguard Worker     uint32_t main_timestamp;
103*d9f75844SAndroid Build Coastguard Worker     uint16_t main_sequence_number;
104*d9f75844SAndroid Build Coastguard Worker     bool is_cng_or_dtmf;
105*d9f75844SAndroid Build Coastguard Worker     bool is_dtx;
106*d9f75844SAndroid Build Coastguard Worker     bool buffer_flush;
107*d9f75844SAndroid Build Coastguard Worker   };
108*d9f75844SAndroid Build Coastguard Worker 
109*d9f75844SAndroid Build Coastguard Worker   virtual ~NetEqController() = default;
110*d9f75844SAndroid Build Coastguard Worker 
111*d9f75844SAndroid Build Coastguard Worker   // Resets object to a clean state.
112*d9f75844SAndroid Build Coastguard Worker   virtual void Reset() = 0;
113*d9f75844SAndroid Build Coastguard Worker 
114*d9f75844SAndroid Build Coastguard Worker   // Resets parts of the state. Typically done when switching codecs.
115*d9f75844SAndroid Build Coastguard Worker   virtual void SoftReset() = 0;
116*d9f75844SAndroid Build Coastguard Worker 
117*d9f75844SAndroid Build Coastguard Worker   // Given info about the latest received packet, and current jitter buffer
118*d9f75844SAndroid Build Coastguard Worker   // status, returns the operation. `target_timestamp` and `expand_mutefactor`
119*d9f75844SAndroid Build Coastguard Worker   // are provided for reference. `last_packet_samples` is the number of samples
120*d9f75844SAndroid Build Coastguard Worker   // obtained from the last decoded frame. If there is a packet available, it
121*d9f75844SAndroid Build Coastguard Worker   // should be supplied in `packet`. The mode resulting from the last call to
122*d9f75844SAndroid Build Coastguard Worker   // NetEqImpl::GetAudio is supplied in `last_mode`. If there is a DTMF event to
123*d9f75844SAndroid Build Coastguard Worker   // play, `play_dtmf` should be set to true. The output variable
124*d9f75844SAndroid Build Coastguard Worker   // `reset_decoder` will be set to true if a reset is required; otherwise it is
125*d9f75844SAndroid Build Coastguard Worker   // left unchanged (i.e., it can remain true if it was true before the call).
126*d9f75844SAndroid Build Coastguard Worker   virtual NetEq::Operation GetDecision(const NetEqStatus& status,
127*d9f75844SAndroid Build Coastguard Worker                                        bool* reset_decoder) = 0;
128*d9f75844SAndroid Build Coastguard Worker 
129*d9f75844SAndroid Build Coastguard Worker   // Inform NetEqController that an empty packet has arrived.
130*d9f75844SAndroid Build Coastguard Worker   virtual void RegisterEmptyPacket() = 0;
131*d9f75844SAndroid Build Coastguard Worker 
132*d9f75844SAndroid Build Coastguard Worker   // Sets the sample rate and the output block size.
133*d9f75844SAndroid Build Coastguard Worker   virtual void SetSampleRate(int fs_hz, size_t output_size_samples) = 0;
134*d9f75844SAndroid Build Coastguard Worker 
135*d9f75844SAndroid Build Coastguard Worker   // Sets a minimum or maximum delay in millisecond.
136*d9f75844SAndroid Build Coastguard Worker   // Returns true if the delay bound is successfully applied, otherwise false.
137*d9f75844SAndroid Build Coastguard Worker   virtual bool SetMaximumDelay(int delay_ms) = 0;
138*d9f75844SAndroid Build Coastguard Worker   virtual bool SetMinimumDelay(int delay_ms) = 0;
139*d9f75844SAndroid Build Coastguard Worker 
140*d9f75844SAndroid Build Coastguard Worker   // Sets a base minimum delay in milliseconds for packet buffer. The effective
141*d9f75844SAndroid Build Coastguard Worker   // minimum delay can't be lower than base minimum delay, even if a lower value
142*d9f75844SAndroid Build Coastguard Worker   // is set using SetMinimumDelay.
143*d9f75844SAndroid Build Coastguard Worker   // Returns true if the base minimum is successfully applied, otherwise false.
144*d9f75844SAndroid Build Coastguard Worker   virtual bool SetBaseMinimumDelay(int delay_ms) = 0;
145*d9f75844SAndroid Build Coastguard Worker   virtual int GetBaseMinimumDelay() const = 0;
146*d9f75844SAndroid Build Coastguard Worker 
147*d9f75844SAndroid Build Coastguard Worker   // These methods test the `cng_state_` for different conditions.
148*d9f75844SAndroid Build Coastguard Worker   virtual bool CngRfc3389On() const = 0;
149*d9f75844SAndroid Build Coastguard Worker   virtual bool CngOff() const = 0;
150*d9f75844SAndroid Build Coastguard Worker 
151*d9f75844SAndroid Build Coastguard Worker   // Resets the `cng_state_` to kCngOff.
152*d9f75844SAndroid Build Coastguard Worker   virtual void SetCngOff() = 0;
153*d9f75844SAndroid Build Coastguard Worker 
154*d9f75844SAndroid Build Coastguard Worker   // Reports back to DecisionLogic whether the decision to do expand remains or
155*d9f75844SAndroid Build Coastguard Worker   // not. Note that this is necessary, since an expand decision can be changed
156*d9f75844SAndroid Build Coastguard Worker   // to kNormal in NetEqImpl::GetDecision if there is still enough data in the
157*d9f75844SAndroid Build Coastguard Worker   // sync buffer.
158*d9f75844SAndroid Build Coastguard Worker   virtual void ExpandDecision(NetEq::Operation operation) = 0;
159*d9f75844SAndroid Build Coastguard Worker 
160*d9f75844SAndroid Build Coastguard Worker   // Adds `value` to `sample_memory_`.
161*d9f75844SAndroid Build Coastguard Worker   virtual void AddSampleMemory(int32_t value) = 0;
162*d9f75844SAndroid Build Coastguard Worker 
163*d9f75844SAndroid Build Coastguard Worker   // Returns the target buffer level in ms.
164*d9f75844SAndroid Build Coastguard Worker   virtual int TargetLevelMs() const = 0;
165*d9f75844SAndroid Build Coastguard Worker 
166*d9f75844SAndroid Build Coastguard Worker   // Returns the target buffer level in ms as it would be if no minimum or
167*d9f75844SAndroid Build Coastguard Worker   // maximum delay was set.
168*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/14270): Make pure virtual once all implementations are
169*d9f75844SAndroid Build Coastguard Worker   // updated.
UnlimitedTargetLevelMs()170*d9f75844SAndroid Build Coastguard Worker   virtual int UnlimitedTargetLevelMs() const { return 0; }
171*d9f75844SAndroid Build Coastguard Worker 
172*d9f75844SAndroid Build Coastguard Worker   // Notify the NetEqController that a packet has arrived. Returns the relative
173*d9f75844SAndroid Build Coastguard Worker   // arrival delay, if it can be computed.
174*d9f75844SAndroid Build Coastguard Worker   virtual absl::optional<int> PacketArrived(int fs_hz,
175*d9f75844SAndroid Build Coastguard Worker                                             bool should_update_stats,
176*d9f75844SAndroid Build Coastguard Worker                                             const PacketArrivedInfo& info) = 0;
177*d9f75844SAndroid Build Coastguard Worker 
178*d9f75844SAndroid Build Coastguard Worker   // Notify the NetEqController that we are currently in muted state.
179*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/14270): Make pure virtual when downstream is updated.
NotifyMutedState()180*d9f75844SAndroid Build Coastguard Worker   virtual void NotifyMutedState() {}
181*d9f75844SAndroid Build Coastguard Worker 
182*d9f75844SAndroid Build Coastguard Worker   // Returns true if a peak was found.
183*d9f75844SAndroid Build Coastguard Worker   virtual bool PeakFound() const = 0;
184*d9f75844SAndroid Build Coastguard Worker 
185*d9f75844SAndroid Build Coastguard Worker   // Get the filtered buffer level in samples.
186*d9f75844SAndroid Build Coastguard Worker   virtual int GetFilteredBufferLevel() const = 0;
187*d9f75844SAndroid Build Coastguard Worker 
188*d9f75844SAndroid Build Coastguard Worker   // Accessors and mutators.
189*d9f75844SAndroid Build Coastguard Worker   virtual void set_sample_memory(int32_t value) = 0;
190*d9f75844SAndroid Build Coastguard Worker   virtual size_t noise_fast_forward() const = 0;
191*d9f75844SAndroid Build Coastguard Worker   virtual size_t packet_length_samples() const = 0;
192*d9f75844SAndroid Build Coastguard Worker   virtual void set_packet_length_samples(size_t value) = 0;
193*d9f75844SAndroid Build Coastguard Worker   virtual void set_prev_time_scale(bool value) = 0;
194*d9f75844SAndroid Build Coastguard Worker };
195*d9f75844SAndroid Build Coastguard Worker 
196*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
197*d9f75844SAndroid Build Coastguard Worker #endif  // API_NETEQ_NETEQ_CONTROLLER_H_
198