OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | |
3 * | |
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 | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include <limits> | |
12 | |
13 #include "webrtc/base/checks.h" | |
14 #include "webrtc/base/logging.h" | |
15 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_s end_time.h" | |
16 #include "webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h" | |
17 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | |
18 #include "webrtc/modules/utility/interface/process_thread.h" | |
19 | |
20 namespace webrtc { | |
21 | |
22 const int64_t kNoTimestamp = -1; | |
23 const int64_t kSendTimeHistoryWindowMs = 10000; | |
24 const int64_t kBaseTimestampScaleFactor = | |
25 rtcp::TransportFeedback::kDeltaScaleFactor * (1 << 8); | |
26 const int64_t kBaseTimestampRangeSizeUs = kBaseTimestampScaleFactor * (1 << 24); | |
27 | |
28 TransportFeedbackAdapter::TransportFeedbackAdapter( | |
29 RtcpBandwidthObserver* bandwidth_observer, | |
30 Clock* clock, | |
31 ProcessThread* process_thread) | |
32 : send_time_history_(kSendTimeHistoryWindowMs), | |
33 rtcp_bandwidth_observer_(bandwidth_observer), | |
34 process_thread_(process_thread), | |
35 clock_(clock), | |
36 current_offset_ms_(kNoTimestamp), | |
37 last_timestamp_us_(kNoTimestamp) {} | |
38 | |
39 TransportFeedbackAdapter::~TransportFeedbackAdapter() { | |
40 if (bitrate_estimator_.get()) | |
41 process_thread_->DeRegisterModule(bitrate_estimator_.get()); | |
42 } | |
43 | |
44 void TransportFeedbackAdapter::SetBitrateEstimator( | |
45 RemoteBitrateEstimator* rbe) { | |
46 if (bitrate_estimator_.get() != rbe) { | |
47 bitrate_estimator_.reset(rbe); | |
48 process_thread_->RegisterModule(rbe); | |
49 } | |
50 } | |
51 | |
52 void TransportFeedbackAdapter::OnPacketSent(const PacketInfo& info) { | |
53 rtc::CritScope cs(&lock_); | |
54 send_time_history_.AddAndRemoveOld(info); | |
55 } | |
56 | |
57 void TransportFeedbackAdapter::OnTransportFeedback( | |
58 const rtcp::TransportFeedback& feedback) { | |
59 int64_t timestamp_us = feedback.GetBaseTimeUs(); | |
60 // Add timestamp deltas to a local time base selected on first packet arrival. | |
61 // This won't be the true time base, but makes it easier to manually inspect | |
62 // time stamps. | |
63 if (last_timestamp_us_ == kNoTimestamp) { | |
64 current_offset_ms_ = clock_->TimeInMilliseconds(); | |
65 } else { | |
66 int64_t delta = timestamp_us - last_timestamp_us_; | |
67 | |
68 // Detect and compensate for wrap-arounds in base time. | |
69 if (std::abs(delta - kBaseTimestampRangeSizeUs) < std::abs(delta)) { | |
70 delta -= kBaseTimestampRangeSizeUs; // Wrap backwards. | |
71 } else if (std::abs(delta + kBaseTimestampRangeSizeUs) < std::abs(delta)) { | |
72 delta += kBaseTimestampRangeSizeUs; // Wrap forwards. | |
73 } | |
74 | |
75 current_offset_ms_ += delta / 1000; | |
76 } | |
77 last_timestamp_us_ = timestamp_us; | |
78 | |
79 uint16_t sequence_number = feedback.GetBaseSequence(); | |
80 std::vector<int64_t> delta_vec = feedback.GetReceiveDeltasUs(); | |
81 auto delta_it = delta_vec.begin(); | |
82 std::vector<PacketInfo> packet_feedback_vector; | |
83 packet_feedback_vector.reserve(delta_vec.size()); | |
84 | |
85 { | |
86 rtc::CritScope cs(&lock_); | |
87 size_t failed_lookups = 0; | |
88 int64_t offset_us = 0; | |
89 for (auto symbol : feedback.GetStatusVector()) { | |
90 if (symbol != rtcp::TransportFeedback::StatusSymbol::kNotReceived) { | |
91 DCHECK(delta_it != delta_vec.end()); | |
92 offset_us += *(delta_it++); | |
93 int64_t timestamp_ms = current_offset_ms_ + (offset_us / 1000); | |
94 PacketInfo info = {timestamp_ms, 0, sequence_number, 0, false}; | |
95 if (send_time_history_.GetInfo(&info, true)) { | |
96 packet_feedback_vector.push_back(info); | |
97 } else { | |
98 ++failed_lookups; | |
99 } | |
100 } | |
101 ++sequence_number; | |
102 } | |
103 DCHECK(delta_it == delta_vec.end()); | |
104 if (failed_lookups > 0) { | |
105 LOG(LS_WARNING) << "Failed to lookup send time for " << failed_lookups | |
kjellander_webrtc
2016/09/29 05:15:51
This warning can spam the logs a lot during a call
| |
106 << " packet" << (failed_lookups > 1 ? "s" : "") | |
107 << ". Send time history too small?"; | |
108 } | |
109 } | |
110 DCHECK(bitrate_estimator_.get() != nullptr); | |
111 bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector); | |
112 } | |
113 | |
114 void TransportFeedbackAdapter::OnReceiveBitrateChanged( | |
115 const std::vector<unsigned int>& ssrcs, | |
116 unsigned int bitrate) { | |
117 rtcp_bandwidth_observer_->OnReceivedEstimatedBitrate(bitrate); | |
118 } | |
119 | |
120 void TransportFeedbackAdapter::OnRttUpdate(int64_t avg_rtt_ms, | |
121 int64_t max_rtt_ms) { | |
122 DCHECK(bitrate_estimator_.get() != nullptr); | |
123 bitrate_estimator_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); | |
124 } | |
125 | |
126 } // namespace webrtc | |
OLD | NEW |