OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/audio_coding/main/acm2/nack.h" | 11 #include "webrtc/modules/audio_coding/neteq/nack.h" |
12 | 12 |
13 #include <assert.h> // For assert. | 13 #include <assert.h> // For assert. |
14 | 14 |
15 #include <algorithm> // For std::max. | 15 #include <algorithm> // For std::max. |
16 | 16 |
| 17 #include "webrtc/base/checks.h" |
17 #include "webrtc/modules/interface/module_common_types.h" | 18 #include "webrtc/modules/interface/module_common_types.h" |
18 #include "webrtc/system_wrappers/include/logging.h" | 19 #include "webrtc/system_wrappers/include/logging.h" |
19 | 20 |
20 namespace webrtc { | 21 namespace webrtc { |
21 | |
22 namespace acm2 { | |
23 | |
24 namespace { | 22 namespace { |
25 | 23 |
26 const int kDefaultSampleRateKhz = 48; | 24 const int kDefaultSampleRateKhz = 48; |
27 const int kDefaultPacketSizeMs = 20; | 25 const int kDefaultPacketSizeMs = 20; |
28 | 26 |
29 } // namespace | 27 } // namespace |
30 | 28 |
31 Nack::Nack(int nack_threshold_packets) | 29 Nack::Nack(int nack_threshold_packets) |
32 : nack_threshold_packets_(nack_threshold_packets), | 30 : nack_threshold_packets_(nack_threshold_packets), |
33 sequence_num_last_received_rtp_(0), | 31 sequence_num_last_received_rtp_(0), |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 | 80 |
83 UpdateList(sequence_number); | 81 UpdateList(sequence_number); |
84 | 82 |
85 sequence_num_last_received_rtp_ = sequence_number; | 83 sequence_num_last_received_rtp_ = sequence_number; |
86 timestamp_last_received_rtp_ = timestamp; | 84 timestamp_last_received_rtp_ = timestamp; |
87 LimitNackListSize(); | 85 LimitNackListSize(); |
88 } | 86 } |
89 | 87 |
90 void Nack::UpdateSamplesPerPacket(uint16_t sequence_number_current_received_rtp, | 88 void Nack::UpdateSamplesPerPacket(uint16_t sequence_number_current_received_rtp, |
91 uint32_t timestamp_current_received_rtp) { | 89 uint32_t timestamp_current_received_rtp) { |
92 uint32_t timestamp_increase = timestamp_current_received_rtp - | 90 uint32_t timestamp_increase = |
93 timestamp_last_received_rtp_; | 91 timestamp_current_received_rtp - timestamp_last_received_rtp_; |
94 uint16_t sequence_num_increase = sequence_number_current_received_rtp - | 92 uint16_t sequence_num_increase = |
95 sequence_num_last_received_rtp_; | 93 sequence_number_current_received_rtp - sequence_num_last_received_rtp_; |
96 | 94 |
97 samples_per_packet_ = timestamp_increase / sequence_num_increase; | 95 samples_per_packet_ = timestamp_increase / sequence_num_increase; |
98 } | 96 } |
99 | 97 |
100 void Nack::UpdateList(uint16_t sequence_number_current_received_rtp) { | 98 void Nack::UpdateList(uint16_t sequence_number_current_received_rtp) { |
101 // Some of the packets which were considered late, now are considered missing. | 99 // Some of the packets which were considered late, now are considered missing. |
102 ChangeFromLateToMissing(sequence_number_current_received_rtp); | 100 ChangeFromLateToMissing(sequence_number_current_received_rtp); |
103 | 101 |
104 if (IsNewerSequenceNumber(sequence_number_current_received_rtp, | 102 if (IsNewerSequenceNumber(sequence_number_current_received_rtp, |
105 sequence_num_last_received_rtp_ + 1)) | 103 sequence_num_last_received_rtp_ + 1)) |
106 AddToList(sequence_number_current_received_rtp); | 104 AddToList(sequence_number_current_received_rtp); |
107 } | 105 } |
108 | 106 |
109 void Nack::ChangeFromLateToMissing( | 107 void Nack::ChangeFromLateToMissing( |
110 uint16_t sequence_number_current_received_rtp) { | 108 uint16_t sequence_number_current_received_rtp) { |
111 NackList::const_iterator lower_bound = nack_list_.lower_bound( | 109 NackList::const_iterator lower_bound = |
112 static_cast<uint16_t>(sequence_number_current_received_rtp - | 110 nack_list_.lower_bound(static_cast<uint16_t>( |
113 nack_threshold_packets_)); | 111 sequence_number_current_received_rtp - nack_threshold_packets_)); |
114 | 112 |
115 for (NackList::iterator it = nack_list_.begin(); it != lower_bound; ++it) | 113 for (NackList::iterator it = nack_list_.begin(); it != lower_bound; ++it) |
116 it->second.is_missing = true; | 114 it->second.is_missing = true; |
117 } | 115 } |
118 | 116 |
119 uint32_t Nack::EstimateTimestamp(uint16_t sequence_num) { | 117 uint32_t Nack::EstimateTimestamp(uint16_t sequence_num) { |
120 uint16_t sequence_num_diff = sequence_num - sequence_num_last_received_rtp_; | 118 uint16_t sequence_num_diff = sequence_num - sequence_num_last_received_rtp_; |
121 return sequence_num_diff * samples_per_packet_ + timestamp_last_received_rtp_; | 119 return sequence_num_diff * samples_per_packet_ + timestamp_last_received_rtp_; |
122 } | 120 } |
123 | 121 |
124 void Nack::AddToList(uint16_t sequence_number_current_received_rtp) { | 122 void Nack::AddToList(uint16_t sequence_number_current_received_rtp) { |
125 assert(!any_rtp_decoded_ || IsNewerSequenceNumber( | 123 assert(!any_rtp_decoded_ || |
126 sequence_number_current_received_rtp, sequence_num_last_decoded_rtp_)); | 124 IsNewerSequenceNumber(sequence_number_current_received_rtp, |
| 125 sequence_num_last_decoded_rtp_)); |
127 | 126 |
128 // Packets with sequence numbers older than |upper_bound_missing| are | 127 // Packets with sequence numbers older than |upper_bound_missing| are |
129 // considered missing, and the rest are considered late. | 128 // considered missing, and the rest are considered late. |
130 uint16_t upper_bound_missing = sequence_number_current_received_rtp - | 129 uint16_t upper_bound_missing = |
131 nack_threshold_packets_; | 130 sequence_number_current_received_rtp - nack_threshold_packets_; |
132 | 131 |
133 for (uint16_t n = sequence_num_last_received_rtp_ + 1; | 132 for (uint16_t n = sequence_num_last_received_rtp_ + 1; |
134 IsNewerSequenceNumber(sequence_number_current_received_rtp, n); ++n) { | 133 IsNewerSequenceNumber(sequence_number_current_received_rtp, n); ++n) { |
135 bool is_missing = IsNewerSequenceNumber(upper_bound_missing, n); | 134 bool is_missing = IsNewerSequenceNumber(upper_bound_missing, n); |
136 uint32_t timestamp = EstimateTimestamp(n); | 135 uint32_t timestamp = EstimateTimestamp(n); |
137 NackElement nack_element(TimeToPlay(timestamp), timestamp, is_missing); | 136 NackElement nack_element(TimeToPlay(timestamp), timestamp, is_missing); |
138 nack_list_.insert(nack_list_.end(), std::make_pair(n, nack_element)); | 137 nack_list_.insert(nack_list_.end(), std::make_pair(n, nack_element)); |
139 } | 138 } |
140 } | 139 } |
141 | 140 |
142 void Nack::UpdateEstimatedPlayoutTimeBy10ms() { | 141 void Nack::UpdateEstimatedPlayoutTimeBy10ms() { |
143 while (!nack_list_.empty() && | 142 while (!nack_list_.empty() && |
144 nack_list_.begin()->second.time_to_play_ms <= 10) | 143 nack_list_.begin()->second.time_to_play_ms <= 10) |
145 nack_list_.erase(nack_list_.begin()); | 144 nack_list_.erase(nack_list_.begin()); |
146 | 145 |
147 for (NackList::iterator it = nack_list_.begin(); it != nack_list_.end(); ++it) | 146 for (NackList::iterator it = nack_list_.begin(); it != nack_list_.end(); ++it) |
148 it->second.time_to_play_ms -= 10; | 147 it->second.time_to_play_ms -= 10; |
149 } | 148 } |
150 | 149 |
151 void Nack::UpdateLastDecodedPacket(uint16_t sequence_number, | 150 void Nack::UpdateLastDecodedPacket(uint16_t sequence_number, |
152 uint32_t timestamp) { | 151 uint32_t timestamp) { |
153 if (IsNewerSequenceNumber(sequence_number, sequence_num_last_decoded_rtp_) || | 152 if (IsNewerSequenceNumber(sequence_number, sequence_num_last_decoded_rtp_) || |
154 !any_rtp_decoded_) { | 153 !any_rtp_decoded_) { |
155 sequence_num_last_decoded_rtp_ = sequence_number; | 154 sequence_num_last_decoded_rtp_ = sequence_number; |
156 timestamp_last_decoded_rtp_ = timestamp; | 155 timestamp_last_decoded_rtp_ = timestamp; |
157 // Packets in the list with sequence numbers less than the | 156 // Packets in the list with sequence numbers less than the |
158 // sequence number of the decoded RTP should be removed from the lists. | 157 // sequence number of the decoded RTP should be removed from the lists. |
159 // They will be discarded by the jitter buffer if they arrive. | 158 // They will be discarded by the jitter buffer if they arrive. |
160 nack_list_.erase(nack_list_.begin(), nack_list_.upper_bound( | 159 nack_list_.erase(nack_list_.begin(), |
161 sequence_num_last_decoded_rtp_)); | 160 nack_list_.upper_bound(sequence_num_last_decoded_rtp_)); |
162 | 161 |
163 // Update estimated time-to-play. | 162 // Update estimated time-to-play. |
164 for (NackList::iterator it = nack_list_.begin(); it != nack_list_.end(); | 163 for (NackList::iterator it = nack_list_.begin(); it != nack_list_.end(); |
165 ++it) | 164 ++it) |
166 it->second.time_to_play_ms = TimeToPlay(it->second.estimated_timestamp); | 165 it->second.time_to_play_ms = TimeToPlay(it->second.estimated_timestamp); |
167 } else { | 166 } else { |
168 assert(sequence_number == sequence_num_last_decoded_rtp_); | 167 assert(sequence_number == sequence_num_last_decoded_rtp_); |
169 | 168 |
170 // Same sequence number as before. 10 ms is elapsed, update estimations for | 169 // Same sequence number as before. 10 ms is elapsed, update estimations for |
171 // time-to-play. | 170 // time-to-play. |
172 UpdateEstimatedPlayoutTimeBy10ms(); | 171 UpdateEstimatedPlayoutTimeBy10ms(); |
173 | 172 |
174 // Update timestamp for better estimate of time-to-play, for packets which | 173 // Update timestamp for better estimate of time-to-play, for packets which |
175 // are added to NACK list later on. | 174 // are added to NACK list later on. |
(...skipping 12 matching lines...) Expand all Loading... |
188 sequence_num_last_received_rtp_ = 0; | 187 sequence_num_last_received_rtp_ = 0; |
189 timestamp_last_received_rtp_ = 0; | 188 timestamp_last_received_rtp_ = 0; |
190 any_rtp_received_ = false; | 189 any_rtp_received_ = false; |
191 sequence_num_last_decoded_rtp_ = 0; | 190 sequence_num_last_decoded_rtp_ = 0; |
192 timestamp_last_decoded_rtp_ = 0; | 191 timestamp_last_decoded_rtp_ = 0; |
193 any_rtp_decoded_ = false; | 192 any_rtp_decoded_ = false; |
194 sample_rate_khz_ = kDefaultSampleRateKhz; | 193 sample_rate_khz_ = kDefaultSampleRateKhz; |
195 samples_per_packet_ = sample_rate_khz_ * kDefaultPacketSizeMs; | 194 samples_per_packet_ = sample_rate_khz_ * kDefaultPacketSizeMs; |
196 } | 195 } |
197 | 196 |
198 int Nack::SetMaxNackListSize(size_t max_nack_list_size) { | 197 void Nack::SetMaxNackListSize(size_t max_nack_list_size) { |
199 if (max_nack_list_size == 0 || max_nack_list_size > kNackListSizeLimit) | 198 RTC_CHECK_GT(max_nack_list_size, 0u); |
200 return -1; | 199 // Ugly hack to get around the problem of passing static consts by reference. |
| 200 const size_t kNackListSizeLimitLocal = Nack::kNackListSizeLimit; |
| 201 RTC_CHECK_LE(max_nack_list_size, kNackListSizeLimitLocal); |
| 202 |
201 max_nack_list_size_ = max_nack_list_size; | 203 max_nack_list_size_ = max_nack_list_size; |
202 LimitNackListSize(); | 204 LimitNackListSize(); |
203 return 0; | |
204 } | 205 } |
205 | 206 |
206 void Nack::LimitNackListSize() { | 207 void Nack::LimitNackListSize() { |
207 uint16_t limit = sequence_num_last_received_rtp_ - | 208 uint16_t limit = sequence_num_last_received_rtp_ - |
208 static_cast<uint16_t>(max_nack_list_size_) - 1; | 209 static_cast<uint16_t>(max_nack_list_size_) - 1; |
209 nack_list_.erase(nack_list_.begin(), nack_list_.upper_bound(limit)); | 210 nack_list_.erase(nack_list_.begin(), nack_list_.upper_bound(limit)); |
210 } | 211 } |
211 | 212 |
212 int64_t Nack::TimeToPlay(uint32_t timestamp) const { | 213 int64_t Nack::TimeToPlay(uint32_t timestamp) const { |
213 uint32_t timestamp_increase = timestamp - timestamp_last_decoded_rtp_; | 214 uint32_t timestamp_increase = timestamp - timestamp_last_decoded_rtp_; |
214 return timestamp_increase / sample_rate_khz_; | 215 return timestamp_increase / sample_rate_khz_; |
215 } | 216 } |
216 | 217 |
217 // We don't erase elements with time-to-play shorter than round-trip-time. | 218 // We don't erase elements with time-to-play shorter than round-trip-time. |
218 std::vector<uint16_t> Nack::GetNackList(int64_t round_trip_time_ms) const { | 219 std::vector<uint16_t> Nack::GetNackList(int64_t round_trip_time_ms) const { |
| 220 RTC_DCHECK_GE(round_trip_time_ms, 0); |
219 std::vector<uint16_t> sequence_numbers; | 221 std::vector<uint16_t> sequence_numbers; |
220 for (NackList::const_iterator it = nack_list_.begin(); it != nack_list_.end(); | 222 for (NackList::const_iterator it = nack_list_.begin(); it != nack_list_.end(); |
221 ++it) { | 223 ++it) { |
222 if (it->second.is_missing && | 224 if (it->second.is_missing && |
223 it->second.time_to_play_ms > round_trip_time_ms) | 225 it->second.time_to_play_ms > round_trip_time_ms) |
224 sequence_numbers.push_back(it->first); | 226 sequence_numbers.push_back(it->first); |
225 } | 227 } |
226 return sequence_numbers; | 228 return sequence_numbers; |
227 } | 229 } |
228 | 230 |
229 } // namespace acm2 | |
230 | |
231 } // namespace webrtc | 231 } // namespace webrtc |
OLD | NEW |