Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: webrtc/modules/audio_coding/main/acm2/nack.h

Issue 1410073006: ACM: Move NACK functionality inside NetEq (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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_MAIN_ACM2_NACK_H_
12 #define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_NACK_H_
13
14 #include <vector>
15 #include <map>
16
17 #include "webrtc/base/scoped_ptr.h"
18 #include "webrtc/modules/audio_coding/main/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 namespace acm2 {
53
54 class Nack {
55 public:
56 // A limit for the size of the NACK list.
57 static const size_t kNackListSizeLimit = 500; // 10 seconds for 20 ms frame
58 // packets.
59 // Factory method.
60 static Nack* Create(int nack_threshold_packets);
61
62 ~Nack();
63
64 // Set a maximum for the size of the NACK list. If the last received packet
65 // has sequence number of N, then NACK list will not contain any element
66 // with sequence number earlier than N - |max_nack_list_size|.
67 //
68 // The largest maximum size is defined by |kNackListSizeLimit|
69 int SetMaxNackListSize(size_t max_nack_list_size);
70
71 // Set the sampling rate.
72 //
73 // If associated sampling rate of the received packets is changed, call this
74 // function to update sampling rate. Note that if there is any change in
75 // received codec then NetEq will flush its buffer and NACK has to be reset.
76 // After Reset() is called sampling rate has to be set.
77 void UpdateSampleRate(int sample_rate_hz);
78
79 // Update the sequence number and the timestamp of the last decoded RTP. This
80 // API should be called every time 10 ms audio is pulled from NetEq.
81 void UpdateLastDecodedPacket(uint16_t sequence_number, uint32_t timestamp);
82
83 // Update the sequence number and the timestamp of the last received RTP. This
84 // API should be called every time a packet pushed into ACM.
85 void UpdateLastReceivedPacket(uint16_t sequence_number, uint32_t timestamp);
86
87 // Get a list of "missing" packets which have expected time-to-play larger
88 // than the given round-trip-time (in milliseconds).
89 // Note: Late packets are not included.
90 std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const;
91
92 // Reset to default values. The NACK list is cleared.
93 // |nack_threshold_packets_| & |max_nack_list_size_| preserve their values.
94 void Reset();
95
96 private:
97 // This test need to access the private method GetNackList().
98 FRIEND_TEST_ALL_PREFIXES(NackTest, EstimateTimestampAndTimeToPlay);
99
100 struct NackElement {
101 NackElement(int64_t initial_time_to_play_ms,
102 uint32_t initial_timestamp,
103 bool missing)
104 : time_to_play_ms(initial_time_to_play_ms),
105 estimated_timestamp(initial_timestamp),
106 is_missing(missing) {}
107
108 // Estimated time (ms) left for this packet to be decoded. This estimate is
109 // updated every time jitter buffer decodes a packet.
110 int64_t time_to_play_ms;
111
112 // A guess about the timestamp of the missing packet, it is used for
113 // estimation of |time_to_play_ms|. The estimate might be slightly wrong if
114 // there has been frame-size change since the last received packet and the
115 // missing packet. However, the risk of this is low, and in case of such
116 // errors, there will be a minor misestimation in time-to-play of missing
117 // packets. This will have a very minor effect on NACK performance.
118 uint32_t estimated_timestamp;
119
120 // True if the packet is considered missing. Otherwise indicates packet is
121 // late.
122 bool is_missing;
123 };
124
125 class NackListCompare {
126 public:
127 bool operator() (uint16_t sequence_number_old,
128 uint16_t sequence_number_new) const {
129 return IsNewerSequenceNumber(sequence_number_new, sequence_number_old);
130 }
131 };
132
133 typedef std::map<uint16_t, NackElement, NackListCompare> NackList;
134
135 // Constructor.
136 explicit Nack(int nack_threshold_packets);
137
138 // This API is used only for testing to assess whether time-to-play is
139 // computed correctly.
140 NackList GetNackList() const;
141
142 // Given the |sequence_number_current_received_rtp| of currently received RTP,
143 // recognize packets which are not arrive and add to the list.
144 void AddToList(uint16_t sequence_number_current_received_rtp);
145
146 // This function subtracts 10 ms of time-to-play for all packets in NACK list.
147 // This is called when 10 ms elapsed with no new RTP packet decoded.
148 void UpdateEstimatedPlayoutTimeBy10ms();
149
150 // Given the |sequence_number_current_received_rtp| and
151 // |timestamp_current_received_rtp| of currently received RTP update number
152 // of samples per packet.
153 void UpdateSamplesPerPacket(uint16_t sequence_number_current_received_rtp,
154 uint32_t timestamp_current_received_rtp);
155
156 // Given the |sequence_number_current_received_rtp| of currently received RTP
157 // update the list. That is; some packets will change from late to missing,
158 // some packets are inserted as missing and some inserted as late.
159 void UpdateList(uint16_t sequence_number_current_received_rtp);
160
161 // Packets which are considered late for too long (according to
162 // |nack_threshold_packets_|) are flagged as missing.
163 void ChangeFromLateToMissing(uint16_t sequence_number_current_received_rtp);
164
165 // Packets which have sequence number older that
166 // |sequence_num_last_received_rtp_| - |max_nack_list_size_| are removed
167 // from the NACK list.
168 void LimitNackListSize();
169
170 // Estimate timestamp of a missing packet given its sequence number.
171 uint32_t EstimateTimestamp(uint16_t sequence_number);
172
173 // Compute time-to-play given a timestamp.
174 int64_t TimeToPlay(uint32_t timestamp) const;
175
176 // If packet N is arrived, any packet prior to N - |nack_threshold_packets_|
177 // which is not arrived is considered missing, and should be in NACK list.
178 // Also any packet in the range of N-1 and N - |nack_threshold_packets_|,
179 // exclusive, which is not arrived is considered late, and should should be
180 // in the list of late packets.
181 const int nack_threshold_packets_;
182
183 // Valid if a packet is received.
184 uint16_t sequence_num_last_received_rtp_;
185 uint32_t timestamp_last_received_rtp_;
186 bool any_rtp_received_; // If any packet received.
187
188 // Valid if a packet is decoded.
189 uint16_t sequence_num_last_decoded_rtp_;
190 uint32_t timestamp_last_decoded_rtp_;
191 bool any_rtp_decoded_; // If any packet decoded.
192
193 int sample_rate_khz_; // Sample rate in kHz.
194
195 // Number of samples per packet. We update this every time we receive a
196 // packet, not only for consecutive packets.
197 int samples_per_packet_;
198
199 // A list of missing packets to be retransmitted. Components of the list
200 // contain the sequence number of missing packets and the estimated time that
201 // each pack is going to be played out.
202 NackList nack_list_;
203
204 // NACK list will not keep track of missing packets prior to
205 // |sequence_num_last_received_rtp_| - |max_nack_list_size_|.
206 size_t max_nack_list_size_;
207 };
208
209 } // namespace acm2
210
211 } // namespace webrtc
212
213 #endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_NACK_H_
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/main/acm2/acm_receiver.cc ('k') | webrtc/modules/audio_coding/main/acm2/nack.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698