OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 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 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 NackModule::NackModule(Clock* clock, | 42 NackModule::NackModule(Clock* clock, |
43 NackSender* nack_sender, | 43 NackSender* nack_sender, |
44 KeyFrameRequestSender* keyframe_request_sender) | 44 KeyFrameRequestSender* keyframe_request_sender) |
45 : clock_(clock), | 45 : clock_(clock), |
46 nack_sender_(nack_sender), | 46 nack_sender_(nack_sender), |
47 keyframe_request_sender_(keyframe_request_sender), | 47 keyframe_request_sender_(keyframe_request_sender), |
48 reordering_histogram_(kNumReorderingBuckets, kMaxReorderedPackets), | 48 reordering_histogram_(kNumReorderingBuckets, kMaxReorderedPackets), |
49 running_(true), | 49 running_(true), |
50 initialized_(false), | 50 initialized_(false), |
51 rtt_ms_(kDefaultRttMs), | 51 rtt_ms_(kDefaultRttMs), |
52 last_seq_num_(0), | 52 newest_seq_num_(0), |
53 next_process_time_ms_(-1) { | 53 next_process_time_ms_(-1) { |
54 RTC_DCHECK(clock_); | 54 RTC_DCHECK(clock_); |
55 RTC_DCHECK(nack_sender_); | 55 RTC_DCHECK(nack_sender_); |
56 RTC_DCHECK(keyframe_request_sender_); | 56 RTC_DCHECK(keyframe_request_sender_); |
57 } | 57 } |
58 | 58 |
59 void NackModule::OnReceivedPacket(const VCMPacket& packet) { | 59 int NackModule::OnReceivedPacket(const VCMPacket& packet) { |
60 rtc::CritScope lock(&crit_); | 60 rtc::CritScope lock(&crit_); |
61 if (!running_) | 61 if (!running_) |
62 return; | 62 return -1; |
63 uint16_t seq_num = packet.seqNum; | 63 uint16_t seq_num = packet.seqNum; |
64 // TODO(philipel): When the packet includes information whether it is | 64 // TODO(philipel): When the packet includes information whether it is |
65 // retransmitted or not, use that value instead. For | 65 // retransmitted or not, use that value instead. For |
66 // now set it to true, which will cause the reordering | 66 // now set it to true, which will cause the reordering |
67 // statistics to never be updated. | 67 // statistics to never be updated. |
68 bool is_retransmitted = true; | 68 bool is_retransmitted = true; |
69 bool is_keyframe = packet.isFirstPacket && packet.frameType == kVideoFrameKey; | 69 bool is_keyframe = packet.isFirstPacket && packet.frameType == kVideoFrameKey; |
70 | 70 |
71 if (!initialized_) { | 71 if (!initialized_) { |
72 last_seq_num_ = seq_num; | 72 newest_seq_num_ = seq_num; |
73 if (is_keyframe) | 73 if (is_keyframe) |
74 keyframe_list_.insert(seq_num); | 74 keyframe_list_.insert(seq_num); |
75 initialized_ = true; | 75 initialized_ = true; |
76 return; | 76 return 0; |
77 } | 77 } |
78 | 78 |
79 if (seq_num == last_seq_num_) | 79 // Since the |newest_seq_num_| is a packet we have actually received we know |
80 return; | 80 // that packet has never been Nacked. |
| 81 if (seq_num == newest_seq_num_) |
| 82 return 0; |
81 | 83 |
82 if (AheadOf(last_seq_num_, seq_num)) { | 84 if (AheadOf(newest_seq_num_, seq_num)) { |
83 // An out of order packet has been received. | 85 // An out of order packet has been received. |
84 nack_list_.erase(seq_num); | 86 auto nack_list_it = nack_list_.find(seq_num); |
| 87 int nacks_sent_for_packet = 0; |
| 88 if (nack_list_it != nack_list_.end()) { |
| 89 nacks_sent_for_packet = nack_list_it->second.retries; |
| 90 nack_list_.erase(nack_list_it); |
| 91 } |
85 if (!is_retransmitted) | 92 if (!is_retransmitted) |
86 UpdateReorderingStatistics(seq_num); | 93 UpdateReorderingStatistics(seq_num); |
87 return; | 94 return nacks_sent_for_packet; |
88 } else { | 95 } |
89 AddPacketsToNack(last_seq_num_ + 1, seq_num); | 96 AddPacketsToNack(newest_seq_num_ + 1, seq_num); |
90 last_seq_num_ = seq_num; | 97 newest_seq_num_ = seq_num; |
91 | 98 |
92 // Keep track of new keyframes. | 99 // Keep track of new keyframes. |
93 if (is_keyframe) | 100 if (is_keyframe) |
94 keyframe_list_.insert(seq_num); | 101 keyframe_list_.insert(seq_num); |
95 | 102 |
96 // And remove old ones so we don't accumulate keyframes. | 103 // And remove old ones so we don't accumulate keyframes. |
97 auto it = keyframe_list_.lower_bound(seq_num - kMaxPacketAge); | 104 auto it = keyframe_list_.lower_bound(seq_num - kMaxPacketAge); |
98 if (it != keyframe_list_.begin()) | 105 if (it != keyframe_list_.begin()) |
99 keyframe_list_.erase(keyframe_list_.begin(), it); | 106 keyframe_list_.erase(keyframe_list_.begin(), it); |
100 | 107 |
101 // Are there any nacks that are waiting for this seq_num. | 108 // Are there any nacks that are waiting for this seq_num. |
102 std::vector<uint16_t> nack_batch = GetNackBatch(kSeqNumOnly); | 109 std::vector<uint16_t> nack_batch = GetNackBatch(kSeqNumOnly); |
103 if (!nack_batch.empty()) | 110 if (!nack_batch.empty()) |
104 nack_sender_->SendNack(nack_batch); | 111 nack_sender_->SendNack(nack_batch); |
105 } | 112 |
| 113 return 0; |
106 } | 114 } |
107 | 115 |
108 void NackModule::ClearUpTo(uint16_t seq_num) { | 116 void NackModule::ClearUpTo(uint16_t seq_num) { |
109 rtc::CritScope lock(&crit_); | 117 rtc::CritScope lock(&crit_); |
110 nack_list_.erase(nack_list_.begin(), nack_list_.lower_bound(seq_num)); | 118 nack_list_.erase(nack_list_.begin(), nack_list_.lower_bound(seq_num)); |
111 keyframe_list_.erase(keyframe_list_.begin(), | 119 keyframe_list_.erase(keyframe_list_.begin(), |
112 keyframe_list_.lower_bound(seq_num)); | 120 keyframe_list_.lower_bound(seq_num)); |
113 } | 121 } |
114 | 122 |
115 void NackModule::UpdateRtt(int64_t rtt_ms) { | 123 void NackModule::UpdateRtt(int64_t rtt_ms) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 } | 216 } |
209 | 217 |
210 std::vector<uint16_t> NackModule::GetNackBatch(NackFilterOptions options) { | 218 std::vector<uint16_t> NackModule::GetNackBatch(NackFilterOptions options) { |
211 bool consider_seq_num = options != kTimeOnly; | 219 bool consider_seq_num = options != kTimeOnly; |
212 bool consider_timestamp = options != kSeqNumOnly; | 220 bool consider_timestamp = options != kSeqNumOnly; |
213 int64_t now_ms = clock_->TimeInMilliseconds(); | 221 int64_t now_ms = clock_->TimeInMilliseconds(); |
214 std::vector<uint16_t> nack_batch; | 222 std::vector<uint16_t> nack_batch; |
215 auto it = nack_list_.begin(); | 223 auto it = nack_list_.begin(); |
216 while (it != nack_list_.end()) { | 224 while (it != nack_list_.end()) { |
217 if (consider_seq_num && it->second.sent_at_time == -1 && | 225 if (consider_seq_num && it->second.sent_at_time == -1 && |
218 AheadOrAt(last_seq_num_, it->second.send_at_seq_num)) { | 226 AheadOrAt(newest_seq_num_, it->second.send_at_seq_num)) { |
219 nack_batch.emplace_back(it->second.seq_num); | 227 nack_batch.emplace_back(it->second.seq_num); |
220 ++it->second.retries; | 228 ++it->second.retries; |
221 it->second.sent_at_time = now_ms; | 229 it->second.sent_at_time = now_ms; |
222 if (it->second.retries >= kMaxNackRetries) { | 230 if (it->second.retries >= kMaxNackRetries) { |
223 LOG(LS_WARNING) << "Sequence number " << it->second.seq_num | 231 LOG(LS_WARNING) << "Sequence number " << it->second.seq_num |
224 << " removed from NACK list due to max retries."; | 232 << " removed from NACK list due to max retries."; |
225 it = nack_list_.erase(it); | 233 it = nack_list_.erase(it); |
226 } else { | 234 } else { |
227 ++it; | 235 ++it; |
228 } | 236 } |
(...skipping 12 matching lines...) Expand all Loading... |
241 ++it; | 249 ++it; |
242 } | 250 } |
243 continue; | 251 continue; |
244 } | 252 } |
245 ++it; | 253 ++it; |
246 } | 254 } |
247 return nack_batch; | 255 return nack_batch; |
248 } | 256 } |
249 | 257 |
250 void NackModule::UpdateReorderingStatistics(uint16_t seq_num) { | 258 void NackModule::UpdateReorderingStatistics(uint16_t seq_num) { |
251 RTC_DCHECK(AheadOf(last_seq_num_, seq_num)); | 259 RTC_DCHECK(AheadOf(newest_seq_num_, seq_num)); |
252 uint16_t diff = ReverseDiff(last_seq_num_, seq_num); | 260 uint16_t diff = ReverseDiff(newest_seq_num_, seq_num); |
253 reordering_histogram_.Add(diff); | 261 reordering_histogram_.Add(diff); |
254 } | 262 } |
255 | 263 |
256 int NackModule::WaitNumberOfPackets(float probability) const { | 264 int NackModule::WaitNumberOfPackets(float probability) const { |
257 if (reordering_histogram_.NumValues() == 0) | 265 if (reordering_histogram_.NumValues() == 0) |
258 return 0; | 266 return 0; |
259 return reordering_histogram_.InverseCdf(probability); | 267 return reordering_histogram_.InverseCdf(probability); |
260 } | 268 } |
261 | 269 |
262 } // namespace webrtc | 270 } // namespace webrtc |
OLD | NEW |