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 28 matching lines...) Expand all Loading... |
39 sent_at_time(-1), | 39 sent_at_time(-1), |
40 retries(0) {} | 40 retries(0) {} |
41 | 41 |
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), | |
50 initialized_(false), | 49 initialized_(false), |
51 rtt_ms_(kDefaultRttMs), | 50 rtt_ms_(kDefaultRttMs), |
52 newest_seq_num_(0), | 51 newest_seq_num_(0), |
53 next_process_time_ms_(-1) { | 52 next_process_time_ms_(-1) { |
54 RTC_DCHECK(clock_); | 53 RTC_DCHECK(clock_); |
55 RTC_DCHECK(nack_sender_); | 54 RTC_DCHECK(nack_sender_); |
56 RTC_DCHECK(keyframe_request_sender_); | 55 RTC_DCHECK(keyframe_request_sender_); |
57 } | 56 } |
58 | 57 |
59 int NackModule::OnReceivedPacket(const VCMPacket& packet) { | 58 int NackModule::OnReceivedPacket(const VCMPacket& packet) { |
60 rtc::CritScope lock(&crit_); | 59 rtc::CritScope lock(&crit_); |
61 if (!running_) | |
62 return -1; | |
63 uint16_t seq_num = packet.seqNum; | 60 uint16_t seq_num = packet.seqNum; |
64 // TODO(philipel): When the packet includes information whether it is | 61 // TODO(philipel): When the packet includes information whether it is |
65 // retransmitted or not, use that value instead. For | 62 // retransmitted or not, use that value instead. For |
66 // now set it to true, which will cause the reordering | 63 // now set it to true, which will cause the reordering |
67 // statistics to never be updated. | 64 // statistics to never be updated. |
68 bool is_retransmitted = true; | 65 bool is_retransmitted = true; |
69 bool is_keyframe = | 66 bool is_keyframe = |
70 packet.is_first_packet_in_frame && packet.frameType == kVideoFrameKey; | 67 packet.is_first_packet_in_frame && packet.frameType == kVideoFrameKey; |
71 | 68 |
72 if (!initialized_) { | 69 if (!initialized_) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 rtc::CritScope lock(&crit_); | 122 rtc::CritScope lock(&crit_); |
126 rtt_ms_ = rtt_ms; | 123 rtt_ms_ = rtt_ms; |
127 } | 124 } |
128 | 125 |
129 void NackModule::Clear() { | 126 void NackModule::Clear() { |
130 rtc::CritScope lock(&crit_); | 127 rtc::CritScope lock(&crit_); |
131 nack_list_.clear(); | 128 nack_list_.clear(); |
132 keyframe_list_.clear(); | 129 keyframe_list_.clear(); |
133 } | 130 } |
134 | 131 |
135 void NackModule::Stop() { | |
136 rtc::CritScope lock(&crit_); | |
137 running_ = false; | |
138 } | |
139 | |
140 int64_t NackModule::TimeUntilNextProcess() { | 132 int64_t NackModule::TimeUntilNextProcess() { |
141 rtc::CritScope lock(&crit_); | |
142 return std::max<int64_t>(next_process_time_ms_ - clock_->TimeInMilliseconds(), | 133 return std::max<int64_t>(next_process_time_ms_ - clock_->TimeInMilliseconds(), |
143 0); | 134 0); |
144 } | 135 } |
145 | 136 |
146 void NackModule::Process() { | 137 void NackModule::Process() { |
147 rtc::CritScope lock(&crit_); | 138 if (nack_sender_) { |
148 if (!running_) | 139 std::vector<uint16_t> nack_batch; |
149 return; | 140 { |
| 141 rtc::CritScope lock(&crit_); |
| 142 nack_batch = GetNackBatch(kTimeOnly); |
| 143 } |
| 144 |
| 145 if (!nack_batch.empty()) |
| 146 nack_sender_->SendNack(nack_batch); |
| 147 } |
150 | 148 |
151 // Update the next_process_time_ms_ in intervals to achieve | 149 // Update the next_process_time_ms_ in intervals to achieve |
152 // the targeted frequency over time. Also add multiple intervals | 150 // the targeted frequency over time. Also add multiple intervals |
153 // in case of a skip in time as to not make uneccessary | 151 // in case of a skip in time as to not make uneccessary |
154 // calls to Process in order to catch up. | 152 // calls to Process in order to catch up. |
155 int64_t now_ms = clock_->TimeInMilliseconds(); | 153 int64_t now_ms = clock_->TimeInMilliseconds(); |
156 if (next_process_time_ms_ == -1) { | 154 if (next_process_time_ms_ == -1) { |
157 next_process_time_ms_ = now_ms + kProcessIntervalMs; | 155 next_process_time_ms_ = now_ms + kProcessIntervalMs; |
158 } else { | 156 } else { |
159 next_process_time_ms_ = next_process_time_ms_ + kProcessIntervalMs + | 157 next_process_time_ms_ = next_process_time_ms_ + kProcessIntervalMs + |
160 (now_ms - next_process_time_ms_) / | 158 (now_ms - next_process_time_ms_) / |
161 kProcessIntervalMs * kProcessIntervalMs; | 159 kProcessIntervalMs * kProcessIntervalMs; |
162 } | 160 } |
163 | |
164 std::vector<uint16_t> nack_batch = GetNackBatch(kTimeOnly); | |
165 if (!nack_batch.empty() && nack_sender_ != nullptr) | |
166 nack_sender_->SendNack(nack_batch); | |
167 } | 161 } |
168 | 162 |
169 bool NackModule::RemovePacketsUntilKeyFrame() { | 163 bool NackModule::RemovePacketsUntilKeyFrame() { |
170 while (!keyframe_list_.empty()) { | 164 while (!keyframe_list_.empty()) { |
171 auto it = nack_list_.lower_bound(*keyframe_list_.begin()); | 165 auto it = nack_list_.lower_bound(*keyframe_list_.begin()); |
172 | 166 |
173 if (it != nack_list_.begin()) { | 167 if (it != nack_list_.begin()) { |
174 // We have found a keyframe that actually is newer than at least one | 168 // We have found a keyframe that actually is newer than at least one |
175 // packet in the nack list. | 169 // packet in the nack list. |
176 RTC_DCHECK(it != nack_list_.end()); | 170 RTC_DCHECK(it != nack_list_.end()); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 reordering_histogram_.Add(diff); | 256 reordering_histogram_.Add(diff); |
263 } | 257 } |
264 | 258 |
265 int NackModule::WaitNumberOfPackets(float probability) const { | 259 int NackModule::WaitNumberOfPackets(float probability) const { |
266 if (reordering_histogram_.NumValues() == 0) | 260 if (reordering_histogram_.NumValues() == 0) |
267 return 0; | 261 return 0; |
268 return reordering_histogram_.InverseCdf(probability); | 262 return reordering_histogram_.InverseCdf(probability); |
269 } | 263 } |
270 | 264 |
271 } // namespace webrtc | 265 } // namespace webrtc |
OLD | NEW |