nack_tracker.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef MODULES_AUDIO_CODING_NETEQ_NACK_TRACKER_H_
  11. #define MODULES_AUDIO_CODING_NETEQ_NACK_TRACKER_H_
  12. #include <stddef.h>
  13. #include <stdint.h>
  14. #include <map>
  15. #include <vector>
  16. #include "modules/include/module_common_types_public.h"
  17. #include "rtc_base/gtest_prod_util.h"
  18. //
  19. // The NackTracker class keeps track of the lost packets, an estimate of
  20. // time-to-play for each packet is also given.
  21. //
  22. // Every time a packet is pushed into NetEq, LastReceivedPacket() has to be
  23. // called to update the NACK list.
  24. //
  25. // Every time 10ms audio is pulled from NetEq LastDecodedPacket() should be
  26. // called, and time-to-play is updated at that moment.
  27. //
  28. // If packet N is received, any packet prior to |N - NackThreshold| which is not
  29. // arrived is considered lost, and should be labeled as "missing" (the size of
  30. // the list might be limited and older packet eliminated from the list). Packets
  31. // |N - NackThreshold|, |N - NackThreshold + 1|, ..., |N - 1| are considered
  32. // "late." A "late" packet with sequence number K is changed to "missing" any
  33. // time a packet with sequence number newer than |K + NackList| is arrived.
  34. //
  35. // The NackTracker class has to know about the sample rate of the packets to
  36. // compute time-to-play. So sample rate should be set as soon as the first
  37. // packet is received. If there is a change in the receive codec (sender changes
  38. // codec) then NackTracker should be reset. This is because NetEQ would flush
  39. // its buffer and re-transmission is meaning less for old packet. Therefore, in
  40. // that case, after reset the sampling rate has to be updated.
  41. //
  42. // Thread Safety
  43. // =============
  44. // Please note that this class in not thread safe. The class must be protected
  45. // if different APIs are called from different threads.
  46. //
  47. namespace webrtc {
  48. class NackTracker {
  49. public:
  50. // A limit for the size of the NACK list.
  51. static const size_t kNackListSizeLimit = 500; // 10 seconds for 20 ms frame
  52. // packets.
  53. // Factory method.
  54. static NackTracker* Create(int nack_threshold_packets);
  55. ~NackTracker();
  56. // Set a maximum for the size of the NACK list. If the last received packet
  57. // has sequence number of N, then NACK list will not contain any element
  58. // with sequence number earlier than N - |max_nack_list_size|.
  59. //
  60. // The largest maximum size is defined by |kNackListSizeLimit|
  61. void SetMaxNackListSize(size_t max_nack_list_size);
  62. // Set the sampling rate.
  63. //
  64. // If associated sampling rate of the received packets is changed, call this
  65. // function to update sampling rate. Note that if there is any change in
  66. // received codec then NetEq will flush its buffer and NACK has to be reset.
  67. // After Reset() is called sampling rate has to be set.
  68. void UpdateSampleRate(int sample_rate_hz);
  69. // Update the sequence number and the timestamp of the last decoded RTP. This
  70. // API should be called every time 10 ms audio is pulled from NetEq.
  71. void UpdateLastDecodedPacket(uint16_t sequence_number, uint32_t timestamp);
  72. // Update the sequence number and the timestamp of the last received RTP. This
  73. // API should be called every time a packet pushed into ACM.
  74. void UpdateLastReceivedPacket(uint16_t sequence_number, uint32_t timestamp);
  75. // Get a list of "missing" packets which have expected time-to-play larger
  76. // than the given round-trip-time (in milliseconds).
  77. // Note: Late packets are not included.
  78. std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const;
  79. // Reset to default values. The NACK list is cleared.
  80. // |nack_threshold_packets_| & |max_nack_list_size_| preserve their values.
  81. void Reset();
  82. private:
  83. // This test need to access the private method GetNackList().
  84. FRIEND_TEST_ALL_PREFIXES(NackTrackerTest, EstimateTimestampAndTimeToPlay);
  85. struct NackElement {
  86. NackElement(int64_t initial_time_to_play_ms,
  87. uint32_t initial_timestamp,
  88. bool missing)
  89. : time_to_play_ms(initial_time_to_play_ms),
  90. estimated_timestamp(initial_timestamp),
  91. is_missing(missing) {}
  92. // Estimated time (ms) left for this packet to be decoded. This estimate is
  93. // updated every time jitter buffer decodes a packet.
  94. int64_t time_to_play_ms;
  95. // A guess about the timestamp of the missing packet, it is used for
  96. // estimation of |time_to_play_ms|. The estimate might be slightly wrong if
  97. // there has been frame-size change since the last received packet and the
  98. // missing packet. However, the risk of this is low, and in case of such
  99. // errors, there will be a minor misestimation in time-to-play of missing
  100. // packets. This will have a very minor effect on NACK performance.
  101. uint32_t estimated_timestamp;
  102. // True if the packet is considered missing. Otherwise indicates packet is
  103. // late.
  104. bool is_missing;
  105. };
  106. class NackListCompare {
  107. public:
  108. bool operator()(uint16_t sequence_number_old,
  109. uint16_t sequence_number_new) const {
  110. return IsNewerSequenceNumber(sequence_number_new, sequence_number_old);
  111. }
  112. };
  113. typedef std::map<uint16_t, NackElement, NackListCompare> NackList;
  114. // Constructor.
  115. explicit NackTracker(int nack_threshold_packets);
  116. // This API is used only for testing to assess whether time-to-play is
  117. // computed correctly.
  118. NackList GetNackList() const;
  119. // Given the |sequence_number_current_received_rtp| of currently received RTP,
  120. // recognize packets which are not arrive and add to the list.
  121. void AddToList(uint16_t sequence_number_current_received_rtp);
  122. // This function subtracts 10 ms of time-to-play for all packets in NACK list.
  123. // This is called when 10 ms elapsed with no new RTP packet decoded.
  124. void UpdateEstimatedPlayoutTimeBy10ms();
  125. // Given the |sequence_number_current_received_rtp| and
  126. // |timestamp_current_received_rtp| of currently received RTP update number
  127. // of samples per packet.
  128. void UpdateSamplesPerPacket(uint16_t sequence_number_current_received_rtp,
  129. uint32_t timestamp_current_received_rtp);
  130. // Given the |sequence_number_current_received_rtp| of currently received RTP
  131. // update the list. That is; some packets will change from late to missing,
  132. // some packets are inserted as missing and some inserted as late.
  133. void UpdateList(uint16_t sequence_number_current_received_rtp);
  134. // Packets which are considered late for too long (according to
  135. // |nack_threshold_packets_|) are flagged as missing.
  136. void ChangeFromLateToMissing(uint16_t sequence_number_current_received_rtp);
  137. // Packets which have sequence number older that
  138. // |sequence_num_last_received_rtp_| - |max_nack_list_size_| are removed
  139. // from the NACK list.
  140. void LimitNackListSize();
  141. // Estimate timestamp of a missing packet given its sequence number.
  142. uint32_t EstimateTimestamp(uint16_t sequence_number);
  143. // Compute time-to-play given a timestamp.
  144. int64_t TimeToPlay(uint32_t timestamp) const;
  145. // If packet N is arrived, any packet prior to N - |nack_threshold_packets_|
  146. // which is not arrived is considered missing, and should be in NACK list.
  147. // Also any packet in the range of N-1 and N - |nack_threshold_packets_|,
  148. // exclusive, which is not arrived is considered late, and should should be
  149. // in the list of late packets.
  150. const int nack_threshold_packets_;
  151. // Valid if a packet is received.
  152. uint16_t sequence_num_last_received_rtp_;
  153. uint32_t timestamp_last_received_rtp_;
  154. bool any_rtp_received_; // If any packet received.
  155. // Valid if a packet is decoded.
  156. uint16_t sequence_num_last_decoded_rtp_;
  157. uint32_t timestamp_last_decoded_rtp_;
  158. bool any_rtp_decoded_; // If any packet decoded.
  159. int sample_rate_khz_; // Sample rate in kHz.
  160. // Number of samples per packet. We update this every time we receive a
  161. // packet, not only for consecutive packets.
  162. int samples_per_packet_;
  163. // A list of missing packets to be retransmitted. Components of the list
  164. // contain the sequence number of missing packets and the estimated time that
  165. // each pack is going to be played out.
  166. NackList nack_list_;
  167. // NACK list will not keep track of missing packets prior to
  168. // |sequence_num_last_received_rtp_| - |max_nack_list_size_|.
  169. size_t max_nack_list_size_;
  170. };
  171. } // namespace webrtc
  172. #endif // MODULES_AUDIO_CODING_NETEQ_NACK_TRACKER_H_