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/remote_bitrate_estimator/inter_arrival.h" | 11 #include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <cassert> | 14 #include <cassert> |
15 | 15 |
16 #include "webrtc/base/logging.h" | 16 #include "webrtc/base/logging.h" |
17 #include "webrtc/modules/include/module_common_types.h" | 17 #include "webrtc/modules/include/module_common_types.h" |
18 | 18 |
19 namespace webrtc { | 19 namespace webrtc { |
20 | 20 |
21 static const int kBurstDeltaThresholdMs = 5; | 21 static const int kBurstDeltaThresholdMs = 5; |
22 | 22 |
23 InterArrival::InterArrival(uint32_t timestamp_group_length_ticks, | 23 InterArrival::InterArrival(uint32_t timestamp_group_length_ticks, |
24 double timestamp_to_ms_coeff, | 24 double timestamp_to_ms_coeff, |
25 bool enable_burst_grouping) | 25 bool enable_burst_grouping) |
26 : kTimestampGroupLengthTicks(timestamp_group_length_ticks), | 26 : kTimestampGroupLengthTicks(timestamp_group_length_ticks), |
27 current_timestamp_group_(), | 27 current_timestamp_group_(), |
28 prev_timestamp_group_(), | 28 prev_timestamp_group_(), |
29 timestamp_to_ms_coeff_(timestamp_to_ms_coeff), | 29 timestamp_to_ms_coeff_(timestamp_to_ms_coeff), |
30 burst_grouping_(enable_burst_grouping) {} | 30 burst_grouping_(enable_burst_grouping), |
31 num_consecutive_reordered_packets_(0) {} | |
31 | 32 |
32 bool InterArrival::ComputeDeltas(uint32_t timestamp, | 33 bool InterArrival::ComputeDeltas(uint32_t timestamp, |
33 int64_t arrival_time_ms, | 34 int64_t arrival_time_ms, |
35 int64_t system_time_ms, | |
34 size_t packet_size, | 36 size_t packet_size, |
35 uint32_t* timestamp_delta, | 37 uint32_t* timestamp_delta, |
36 int64_t* arrival_time_delta_ms, | 38 int64_t* arrival_time_delta_ms, |
37 int* packet_size_delta) { | 39 int* packet_size_delta) { |
38 assert(timestamp_delta != NULL); | 40 assert(timestamp_delta != NULL); |
39 assert(arrival_time_delta_ms != NULL); | 41 assert(arrival_time_delta_ms != NULL); |
40 assert(packet_size_delta != NULL); | 42 assert(packet_size_delta != NULL); |
41 bool calculated_deltas = false; | 43 bool calculated_deltas = false; |
42 if (current_timestamp_group_.IsFirstPacket()) { | 44 if (current_timestamp_group_.IsFirstPacket()) { |
43 // We don't have enough data to update the filter, so we store it until we | 45 // We don't have enough data to update the filter, so we store it until we |
44 // have two frames of data to process. | 46 // have two frames of data to process. |
45 current_timestamp_group_.timestamp = timestamp; | 47 current_timestamp_group_.timestamp = timestamp; |
46 current_timestamp_group_.first_timestamp = timestamp; | 48 current_timestamp_group_.first_timestamp = timestamp; |
47 } else if (!PacketInOrder(timestamp)) { | 49 } else if (!PacketInOrder(timestamp)) { |
48 return false; | 50 return false; |
49 } else if (NewTimestampGroup(arrival_time_ms, timestamp)) { | 51 } else if (NewTimestampGroup(arrival_time_ms, timestamp)) { |
50 // First packet of a later frame, the previous frame sample is ready. | 52 // First packet of a later frame, the previous frame sample is ready. |
51 if (prev_timestamp_group_.complete_time_ms >= 0) { | 53 if (prev_timestamp_group_.complete_time_ms >= 0) { |
52 *timestamp_delta = current_timestamp_group_.timestamp - | 54 *timestamp_delta = current_timestamp_group_.timestamp - |
53 prev_timestamp_group_.timestamp; | 55 prev_timestamp_group_.timestamp; |
54 *arrival_time_delta_ms = current_timestamp_group_.complete_time_ms - | 56 *arrival_time_delta_ms = current_timestamp_group_.complete_time_ms - |
55 prev_timestamp_group_.complete_time_ms; | 57 prev_timestamp_group_.complete_time_ms; |
58 // Check system time differences to see if we have an unproportional jump | |
59 // in arrival time. In that case reset the inter-arrival computations. | |
60 int64_t system_time_delta_ms = | |
61 current_timestamp_group_.last_system_time_ms - | |
62 prev_timestamp_group_.last_system_time_ms; | |
63 if (*arrival_time_delta_ms > system_time_delta_ms) { | |
sprang_webrtc
2016/07/06 12:46:36
I'm not sure I follow. arrival_time_delta_ms is th
stefan-webrtc
2016/07/06 14:53:24
You are right, changed after offline discussion.
| |
64 LOG(LS_WARNING) << "The arrival time clock offset has changed (diff = " | |
65 << *arrival_time_delta_ms - system_time_delta_ms | |
66 << " ms), resetting."; | |
67 Reset(); | |
68 return false; | |
69 } | |
56 if (*arrival_time_delta_ms < 0) { | 70 if (*arrival_time_delta_ms < 0) { |
57 // The group of packets has been reordered since receiving its local | 71 // The group of packets has been reordered since receiving its local |
58 // arrival timestamp. | 72 // arrival timestamp. |
59 LOG(LS_WARNING) << "Packets are being reordered on the path from the " | 73 ++num_consecutive_reordered_packets_; |
60 "socket to the bandwidth estimator. Ignoring this " | 74 if (num_consecutive_reordered_packets_ >= 2) { |
sprang_webrtc
2016/07/06 12:46:36
Is 2 enough?
Make this a public named constant so
stefan-webrtc
2016/07/06 14:53:24
3 should be enough...
| |
61 "packet for bandwidth estimation."; | 75 LOG(LS_WARNING) << "Packets are being reordered on the path from the " |
76 "socket to the bandwidth estimator. Ignoring this " | |
77 "packet for bandwidth estimation, resetting."; | |
78 Reset(); | |
79 } | |
62 return false; | 80 return false; |
81 } else { | |
82 num_consecutive_reordered_packets_ = 0; | |
63 } | 83 } |
64 assert(*arrival_time_delta_ms >= 0); | 84 assert(*arrival_time_delta_ms >= 0); |
65 *packet_size_delta = static_cast<int>(current_timestamp_group_.size) - | 85 *packet_size_delta = static_cast<int>(current_timestamp_group_.size) - |
66 static_cast<int>(prev_timestamp_group_.size); | 86 static_cast<int>(prev_timestamp_group_.size); |
67 calculated_deltas = true; | 87 calculated_deltas = true; |
68 } | 88 } |
69 prev_timestamp_group_ = current_timestamp_group_; | 89 prev_timestamp_group_ = current_timestamp_group_; |
70 // The new timestamp is now the current frame. | 90 // The new timestamp is now the current frame. |
71 current_timestamp_group_.first_timestamp = timestamp; | 91 current_timestamp_group_.first_timestamp = timestamp; |
72 current_timestamp_group_.timestamp = timestamp; | 92 current_timestamp_group_.timestamp = timestamp; |
73 current_timestamp_group_.size = 0; | 93 current_timestamp_group_.size = 0; |
74 } else { | 94 } else { |
75 current_timestamp_group_.timestamp = LatestTimestamp( | 95 current_timestamp_group_.timestamp = LatestTimestamp( |
76 current_timestamp_group_.timestamp, timestamp); | 96 current_timestamp_group_.timestamp, timestamp); |
77 } | 97 } |
78 // Accumulate the frame size. | 98 // Accumulate the frame size. |
79 current_timestamp_group_.size += packet_size; | 99 current_timestamp_group_.size += packet_size; |
80 current_timestamp_group_.complete_time_ms = arrival_time_ms; | 100 current_timestamp_group_.complete_time_ms = arrival_time_ms; |
101 current_timestamp_group_.last_system_time_ms = system_time_ms; | |
81 | 102 |
82 return calculated_deltas; | 103 return calculated_deltas; |
83 } | 104 } |
84 | 105 |
85 bool InterArrival::PacketInOrder(uint32_t timestamp) { | 106 bool InterArrival::PacketInOrder(uint32_t timestamp) { |
86 if (current_timestamp_group_.IsFirstPacket()) { | 107 if (current_timestamp_group_.IsFirstPacket()) { |
87 return true; | 108 return true; |
88 } else { | 109 } else { |
89 // Assume that a diff which is bigger than half the timestamp interval | 110 // Assume that a diff which is bigger than half the timestamp interval |
90 // (32 bits) must be due to reordering. This code is almost identical to | 111 // (32 bits) must be due to reordering. This code is almost identical to |
(...skipping 28 matching lines...) Expand all Loading... | |
119 int64_t arrival_time_delta_ms = arrival_time_ms - | 140 int64_t arrival_time_delta_ms = arrival_time_ms - |
120 current_timestamp_group_.complete_time_ms; | 141 current_timestamp_group_.complete_time_ms; |
121 uint32_t timestamp_diff = timestamp - current_timestamp_group_.timestamp; | 142 uint32_t timestamp_diff = timestamp - current_timestamp_group_.timestamp; |
122 int64_t ts_delta_ms = timestamp_to_ms_coeff_ * timestamp_diff + 0.5; | 143 int64_t ts_delta_ms = timestamp_to_ms_coeff_ * timestamp_diff + 0.5; |
123 if (ts_delta_ms == 0) | 144 if (ts_delta_ms == 0) |
124 return true; | 145 return true; |
125 int propagation_delta_ms = arrival_time_delta_ms - ts_delta_ms; | 146 int propagation_delta_ms = arrival_time_delta_ms - ts_delta_ms; |
126 return propagation_delta_ms < 0 && | 147 return propagation_delta_ms < 0 && |
127 arrival_time_delta_ms <= kBurstDeltaThresholdMs; | 148 arrival_time_delta_ms <= kBurstDeltaThresholdMs; |
128 } | 149 } |
150 | |
151 void InterArrival::Reset() { | |
152 num_consecutive_reordered_packets_ = 0; | |
153 current_timestamp_group_ = TimestampGroup(); | |
154 prev_timestamp_group_ = TimestampGroup(); | |
155 } | |
129 } // namespace webrtc | 156 } // namespace webrtc |
OLD | NEW |