19a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org/*
29a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
39a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *
49a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  Use of this source code is governed by a BSD-style license
59a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  that can be found in the LICENSE file in the root of the source
69a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  tree. An additional intellectual property rights grant can be found
79a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  in the file PATENTS.  All contributing project authors may
89a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
99a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org */
109a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
11e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_DELAY_MANAGER_H_
12e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_DELAY_MANAGER_H_
139a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
143f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <string.h>  // Provide access to size_t.
153f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org
169a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include <vector>
179a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
18774b3d38a4a0f1a8ec08972a3c543cb5d607ce13henrike@webrtc.org#include "webrtc/base/constructormagic.h"
19e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
209a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include "webrtc/typedefs.h"
219a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
229a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgnamespace webrtc {
239a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
249a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Forward declaration.
259a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgclass DelayPeakDetector;
269a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
279a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgclass DelayManager {
289a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org public:
299a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  typedef std::vector<int> IATVector;
309a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
319a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Create a DelayManager object. Notify the delay manager that the packet
329a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // buffer can hold no more than |max_packets_in_buffer| packets (i.e., this
339a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // is the number of packet slots in the buffer). Supply a PeakDetector
349a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // object to the DelayManager.
359a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  DelayManager(int max_packets_in_buffer, DelayPeakDetector* peak_detector);
369a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
37dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org  virtual ~DelayManager();
389a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
399a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Read the inter-arrival time histogram. Mainly for testing purposes.
40dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org  virtual const IATVector& iat_vector() const;
419a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
429a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Updates the delay manager with a new incoming packet, with
439a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // |sequence_number| and |timestamp| from the RTP header. This updates the
449a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // inter-arrival time histogram and other statistics, as well as the
459a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // associated DelayPeakDetector. A new target buffer level is calculated.
469a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Returns 0 on success, -1 on failure (invalid sample rate).
479a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual int Update(uint16_t sequence_number,
489a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                     uint32_t timestamp,
499a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                     int sample_rate_hz);
509a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
519a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Calculates a new target buffer level. Called from the Update() method.
529a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Sets target_level_ (in Q8) and returns the same value. Also calculates
539a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // and updates base_target_level_, which is the target buffer level before
549a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // taking delay peaks into account.
559a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual int CalculateTargetLevel(int iat_packets);
569a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
579a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Notifies the DelayManager of how much audio data is carried in each packet.
589a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // The method updates the DelayPeakDetector too, and resets the inter-arrival
599a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // time counter. Returns 0 on success, -1 on failure.
609a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual int SetPacketAudioLength(int length_ms);
619a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
629a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Resets the DelayManager and the associated DelayPeakDetector.
639a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual void Reset();
649a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
659a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Calculates the average inter-arrival time deviation from the histogram.
669a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // The result is returned as parts-per-million deviation from the nominal
679a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // inter-arrival time. That is, if the average inter-arrival time is equal to
689a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // the nominal frame time, the return value is zero. A positive value
699a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // corresponds to packet spacing being too large, while a negative value means
709a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // that the packets arrive with less spacing than expected.
719a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual int AverageIAT() const;
729a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
739a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Returns true if peak-mode is active. That is, delay peaks were observed
749a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // recently. This method simply asks for the same information from the
759a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // DelayPeakDetector object.
769a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual bool PeakFound() const;
779a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
789a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Notifies the counters in DelayManager and DelayPeakDetector that
799a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // |elapsed_time_ms| have elapsed.
809a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual void UpdateCounters(int elapsed_time_ms);
819a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
829a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Reset the inter-arrival time counter to 0.
83dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org  virtual void ResetPacketIatCount();
849a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
859a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Writes the lower and higher limits which the buffer level should stay
869a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // within to the corresponding pointers. The values are in (fractions of)
879a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // packets in Q8.
889a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual void BufferLimits(int* lower_limit, int* higher_limit) const;
899a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
909a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Gets the target buffer level, in (fractions of) packets in Q8. This value
919a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // includes any extra delay set through the set_extra_delay_ms() method.
929a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual int TargetLevel() const;
939a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
949a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual void LastDecoderType(NetEqDecoder decoder_type);
959a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
969a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Accessors and mutators.
97662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org  // Assuming |delay| is in valid range.
98662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org  virtual bool SetMinimumDelay(int delay_ms);
99662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org  virtual bool SetMaximumDelay(int delay_ms);
100662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org  virtual int least_required_delay_ms() const;
101dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org  virtual int base_target_level() const;
102dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org  virtual void set_streaming_mode(bool value);
103dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org  virtual int last_pack_cng_or_dtmf() const;
104dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org  virtual void set_last_pack_cng_or_dtmf(int value);
1059a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1069a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org private:
1079a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kLimitProbability = 53687091;  // 1/20 in Q30.
1089a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kLimitProbabilityStreaming = 536871;  // 1/2000 in Q30.
1099a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kMaxStreamingPeakPeriodMs = 600000;  // 10 minutes in ms.
1109a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kCumulativeSumDrift = 2;  // Drift term for cumulative sum
1119a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                                             // |iat_cumulative_sum_|.
1129a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Steady-state forgetting factor for |iat_vector_|, 0.9993 in Q15.
1139a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kIatFactor_ = 32745;
1149a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kMaxIat = 64;  // Max inter-arrival time to register.
1159a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1169a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Sets |iat_vector_| to the default start distribution and sets the
1179a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // |base_target_level_| and |target_level_| to the corresponding values.
1189a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  void ResetHistogram();
1199a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1209a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Updates |iat_cumulative_sum_| and |max_iat_cumulative_sum_|. (These are
1219a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // used by the streaming mode.) This method is called by Update().
1229a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  void UpdateCumulativeSums(int packet_len_ms, uint16_t sequence_number);
1239a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1249a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Updates the histogram |iat_vector_|. The probability for inter-arrival time
1259a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // equal to |iat_packets| (in integer packets) is increased slightly, while
1269a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // all other entries are decreased. This method is called by Update().
1279a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  void UpdateHistogram(size_t iat_packets);
1289a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1299a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Makes sure that |target_level_| is not too large, taking
1309a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // |max_packets_in_buffer_| and |extra_delay_ms_| into account. This method is
1319a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // called by Update().
1329a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  void LimitTargetLevel();
1339a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1349a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  bool first_packet_received_;
1359a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  const int max_packets_in_buffer_;  // Capacity of the packet buffer.
1369a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  IATVector iat_vector_;  // Histogram of inter-arrival times.
1379a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int iat_factor_;  // Forgetting factor for updating the IAT histogram (Q15).
1389a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int packet_iat_count_ms_;  // Milliseconds elapsed since last packet.
1399a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int base_target_level_;   // Currently preferred buffer level before peak
1409a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                            // detection and streaming mode (Q0).
141662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org  // TODO(turajs) change the comment according to the implementation of
142662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org  // minimum-delay.
1439a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int target_level_;  // Currently preferred buffer level in (fractions)
1449a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                      // of packets (Q8), before adding any extra delay.
1459a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int packet_len_ms_;  // Length of audio in each incoming packet [ms].
1469a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  bool streaming_mode_;
1479a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  uint16_t last_seq_no_;  // Sequence number for last received packet.
1489a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  uint32_t last_timestamp_;  // Timestamp for the last received packet.
149662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org  int minimum_delay_ms_;  // Externally set minimum delay.
150662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org  int least_required_delay_ms_;  // Smallest preferred buffer level (same unit
151662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org                              // as |target_level_|), before applying
152662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org                              // |minimum_delay_ms_| and/or |maximum_delay_ms_|.
153662ded4a6ddcecf571d31a9ba1469d50652fe0f9turaj@webrtc.org  int maximum_delay_ms_;  // Externally set maximum allowed delay.
1549a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int iat_cumulative_sum_;  // Cumulative sum of delta inter-arrival times.
1559a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int max_iat_cumulative_sum_;  // Max of |iat_cumulative_sum_|.
1569a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int max_timer_ms_;  // Time elapsed since maximum was observed.
1579a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  DelayPeakDetector& peak_detector_;
1589a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int last_pack_cng_or_dtmf_;
1599a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1609a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  DISALLOW_COPY_AND_ASSIGN(DelayManager);
1619a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org};
1629a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1639a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}  // namespace webrtc
164e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_DELAY_MANAGER_H_
165