summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/api/neteq/neteq_controller.h
blob: f0101d3d1a5661e183f850bfc89d8257e7d00424 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*
 *  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_no_dtx;
    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;

  // These methods test the `cng_state_` for different conditions.
  virtual bool CngRfc3389On() const = 0;
  virtual bool CngOff() const = 0;

  // Resets the `cng_state_` to kCngOff.
  virtual void SetCngOff() = 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_