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