/* * 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 #include #include #include #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 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; // Notify the NetEqController that a packet has arrived. Returns the relative // arrival delay, if it can be computed. virtual absl::optional PacketArrived(int fs_hz, bool should_update_stats, const PacketArrivedInfo& info) = 0; // Notify the NetEqController that we are currently in muted state. // TODO(ivoc): 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_