OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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/test/fake_network_pipe.h" | 11 #include "webrtc/test/fake_network_pipe.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 #include <math.h> | 14 #include <math.h> |
15 #include <string.h> | 15 #include <string.h> |
16 | 16 |
17 #include <algorithm> | 17 #include <algorithm> |
18 #include <cmath> | 18 #include <cmath> |
19 | 19 |
20 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
21 #include "webrtc/call/call.h" | 21 #include "webrtc/call/call.h" |
22 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | |
22 #include "webrtc/system_wrappers/include/clock.h" | 23 #include "webrtc/system_wrappers/include/clock.h" |
23 | 24 |
24 namespace webrtc { | 25 namespace webrtc { |
25 | 26 |
26 namespace { | 27 namespace { |
27 constexpr int64_t kDefaultProcessIntervalMs = 5; | 28 constexpr int64_t kDefaultProcessIntervalMs = 5; |
28 } | 29 } |
29 | 30 |
31 DemuxerImpl::DemuxerImpl(const std::map<uint8_t, MediaType>& payload_type_map) | |
32 : packet_receiver_(nullptr), payload_type_map_(payload_type_map) {} | |
33 | |
34 void DemuxerImpl::SetReceiver(PacketReceiver* receiver) { | |
35 packet_receiver_ = receiver; | |
36 } | |
37 | |
38 void DemuxerImpl::DeliverPacket(const NetworkPacket* packet, | |
39 const PacketTime& packet_time) { | |
40 if (!packet_receiver_) | |
41 return; | |
42 const uint8_t* const packet_data = packet->data(); | |
43 const size_t packet_length = packet->data_length(); | |
44 MediaType media_type = MediaType::ANY; | |
45 if (!RtpHeaderParser::IsRtcp(packet_data, packet_length)) { | |
46 RTC_CHECK_GE(packet_length, 2); | |
47 const uint8_t payload_type = packet_data[1] & 0x7f; | |
48 std::map<uint8_t, MediaType>::const_iterator it = | |
49 payload_type_map_.find(payload_type); | |
50 RTC_CHECK(it != payload_type_map_.end()) | |
51 << "payload type " << static_cast<int>(payload_type) << " unknown."; | |
52 media_type = it->second; | |
53 } | |
54 packet_receiver_->DeliverPacket(media_type, packet_data, packet_length, | |
55 packet_time); | |
56 } | |
57 | |
30 FakeNetworkPipe::FakeNetworkPipe(Clock* clock, | 58 FakeNetworkPipe::FakeNetworkPipe(Clock* clock, |
31 const FakeNetworkPipe::Config& config, | 59 const FakeNetworkPipe::Config& config, |
32 MediaType media_type) | 60 std::unique_ptr<Demuxer> demuxer) |
33 : FakeNetworkPipe(clock, config, media_type, 1) {} | 61 : FakeNetworkPipe(clock, config, std::move(demuxer), 1) {} |
34 | 62 |
35 FakeNetworkPipe::FakeNetworkPipe(Clock* clock, | 63 FakeNetworkPipe::FakeNetworkPipe(Clock* clock, |
36 const FakeNetworkPipe::Config& config, | 64 const FakeNetworkPipe::Config& config, |
37 MediaType media_type, | 65 std::unique_ptr<Demuxer> demuxer, |
38 uint64_t seed) | 66 uint64_t seed) |
39 : clock_(clock), | 67 : clock_(clock), |
40 media_type_(media_type), | 68 demuxer_(std::move(demuxer)), |
41 packet_receiver_(NULL), | |
42 random_(seed), | 69 random_(seed), |
43 config_(), | 70 config_(), |
44 dropped_packets_(0), | 71 dropped_packets_(0), |
45 sent_packets_(0), | 72 sent_packets_(0), |
46 total_packet_delay_(0), | 73 total_packet_delay_(0), |
47 bursting_(false), | 74 bursting_(false), |
48 next_process_time_(clock_->TimeInMilliseconds()), | 75 next_process_time_(clock_->TimeInMilliseconds()), |
49 last_log_time_(clock_->TimeInMilliseconds()) { | 76 last_log_time_(clock_->TimeInMilliseconds()) { |
50 SetConfig(config); | 77 SetConfig(config); |
51 } | 78 } |
52 | 79 |
53 FakeNetworkPipe::~FakeNetworkPipe() { | 80 FakeNetworkPipe::~FakeNetworkPipe() { |
54 while (!capacity_link_.empty()) { | 81 while (!capacity_link_.empty()) { |
55 delete capacity_link_.front(); | 82 delete capacity_link_.front(); |
56 capacity_link_.pop(); | 83 capacity_link_.pop(); |
57 } | 84 } |
58 while (!delay_link_.empty()) { | 85 while (!delay_link_.empty()) { |
59 delete *delay_link_.begin(); | 86 delete *delay_link_.begin(); |
60 delay_link_.erase(delay_link_.begin()); | 87 delay_link_.erase(delay_link_.begin()); |
61 } | 88 } |
62 } | 89 } |
63 | 90 |
64 void FakeNetworkPipe::SetReceiver(PacketReceiver* receiver) { | 91 void FakeNetworkPipe::SetReceiver(PacketReceiver* receiver) { |
65 packet_receiver_ = receiver; | 92 if (!demuxer_) |
perkj_webrtc
2017/04/07 14:24:15
demuxer always exists right? It is moved into the
minyue-webrtc
2017/04/10 09:56:10
Yes, that would be nice.
| |
93 return; | |
94 demuxer_->SetReceiver(receiver); | |
66 } | 95 } |
67 | 96 |
68 void FakeNetworkPipe::SetConfig(const FakeNetworkPipe::Config& config) { | 97 void FakeNetworkPipe::SetConfig(const FakeNetworkPipe::Config& config) { |
69 rtc::CritScope crit(&lock_); | 98 rtc::CritScope crit(&lock_); |
70 config_ = config; // Shallow copy of the struct. | 99 config_ = config; // Shallow copy of the struct. |
71 double prob_loss = config.loss_percent / 100.0; | 100 double prob_loss = config.loss_percent / 100.0; |
72 if (config_.avg_burst_loss_length == -1) { | 101 if (config_.avg_burst_loss_length == -1) { |
73 // Uniform loss | 102 // Uniform loss |
74 prob_loss_bursting_ = prob_loss; | 103 prob_loss_bursting_ = prob_loss; |
75 prob_start_bursting_ = prob_loss; | 104 prob_start_bursting_ = prob_loss; |
76 } else { | 105 } else { |
77 // Lose packets according to a gilbert-elliot model. | 106 // Lose packets according to a gilbert-elliot model. |
78 int avg_burst_loss_length = config.avg_burst_loss_length; | 107 int avg_burst_loss_length = config.avg_burst_loss_length; |
79 int min_avg_burst_loss_length = std::ceil(prob_loss / (1 - prob_loss)); | 108 int min_avg_burst_loss_length = std::ceil(prob_loss / (1 - prob_loss)); |
80 | 109 |
81 RTC_CHECK_GT(avg_burst_loss_length, min_avg_burst_loss_length) | 110 RTC_CHECK_GT(avg_burst_loss_length, min_avg_burst_loss_length) |
82 << "For a total packet loss of " << config.loss_percent << "%% then" | 111 << "For a total packet loss of " << config.loss_percent << "%% then" |
83 << " avg_burst_loss_length must be " << min_avg_burst_loss_length + 1 | 112 << " avg_burst_loss_length must be " << min_avg_burst_loss_length + 1 |
84 << " or higher."; | 113 << " or higher."; |
85 | 114 |
86 prob_loss_bursting_ = (1.0 - 1.0 / avg_burst_loss_length); | 115 prob_loss_bursting_ = (1.0 - 1.0 / avg_burst_loss_length); |
87 prob_start_bursting_ = prob_loss / (1 - prob_loss) / avg_burst_loss_length; | 116 prob_start_bursting_ = prob_loss / (1 - prob_loss) / avg_burst_loss_length; |
88 } | 117 } |
89 } | 118 } |
90 | 119 |
91 void FakeNetworkPipe::SendPacket(const uint8_t* data, size_t data_length) { | 120 void FakeNetworkPipe::SendPacket(const uint8_t* data, size_t data_length) { |
92 // A NULL packet_receiver_ means that this pipe will terminate the flow of | 121 // No demuxer means that this pipe will terminate the flow of packets. |
93 // packets. | 122 if (!demuxer_) |
stefan-webrtc
2017/04/10 07:45:26
As Per pointed out above, this can also be removed
minyue-webrtc
2017/04/10 09:56:10
Done.
| |
94 if (packet_receiver_ == NULL) | |
95 return; | 123 return; |
96 rtc::CritScope crit(&lock_); | 124 rtc::CritScope crit(&lock_); |
97 if (config_.queue_length_packets > 0 && | 125 if (config_.queue_length_packets > 0 && |
98 capacity_link_.size() >= config_.queue_length_packets) { | 126 capacity_link_.size() >= config_.queue_length_packets) { |
99 // Too many packet on the link, drop this one. | 127 // Too many packet on the link, drop this one. |
100 ++dropped_packets_; | 128 ++dropped_packets_; |
101 return; | 129 return; |
102 } | 130 } |
103 | 131 |
104 int64_t time_now = clock_->TimeInMilliseconds(); | 132 int64_t time_now = clock_->TimeInMilliseconds(); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 // |time_now| might be later than when the packet should have arrived, due | 223 // |time_now| might be later than when the packet should have arrived, due |
196 // to NetworkProcess being called too late. For stats, use the time it | 224 // to NetworkProcess being called too late. For stats, use the time it |
197 // should have been on the link. | 225 // should have been on the link. |
198 total_packet_delay_ += packet->arrival_time() - packet->send_time(); | 226 total_packet_delay_ += packet->arrival_time() - packet->send_time(); |
199 } | 227 } |
200 sent_packets_ += packets_to_deliver.size(); | 228 sent_packets_ += packets_to_deliver.size(); |
201 } | 229 } |
202 while (!packets_to_deliver.empty()) { | 230 while (!packets_to_deliver.empty()) { |
203 NetworkPacket* packet = packets_to_deliver.front(); | 231 NetworkPacket* packet = packets_to_deliver.front(); |
204 packets_to_deliver.pop(); | 232 packets_to_deliver.pop(); |
205 packet_receiver_->DeliverPacket(media_type_, packet->data(), | 233 demuxer_->DeliverPacket(packet, PacketTime()); |
206 packet->data_length(), PacketTime()); | |
207 delete packet; | 234 delete packet; |
208 } | 235 } |
209 | 236 |
210 next_process_time_ = !delay_link_.empty() | 237 next_process_time_ = !delay_link_.empty() |
211 ? (*delay_link_.begin())->arrival_time() | 238 ? (*delay_link_.begin())->arrival_time() |
212 : time_now + kDefaultProcessIntervalMs; | 239 : time_now + kDefaultProcessIntervalMs; |
213 } | 240 } |
214 | 241 |
215 int64_t FakeNetworkPipe::TimeUntilNextProcess() const { | 242 int64_t FakeNetworkPipe::TimeUntilNextProcess() const { |
216 rtc::CritScope crit(&lock_); | 243 rtc::CritScope crit(&lock_); |
217 return std::max<int64_t>(next_process_time_ - clock_->TimeInMilliseconds(), | 244 return std::max<int64_t>(next_process_time_ - clock_->TimeInMilliseconds(), |
218 0); | 245 0); |
219 } | 246 } |
220 | 247 |
221 } // namespace webrtc | 248 } // namespace webrtc |
OLD | NEW |