OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/cast/net/rtcp/rtcp.h" | 5 #include "media/cast/net/rtcp/rtcp.h" |
6 | 6 |
7 #include "base/big_endian.h" | |
8 #include "media/cast/cast_config.h" | 7 #include "media/cast/cast_config.h" |
9 #include "media/cast/cast_defines.h" | 8 #include "media/cast/cast_defines.h" |
10 #include "media/cast/cast_environment.h" | 9 #include "media/cast/cast_environment.h" |
11 #include "media/cast/net/cast_transport_defines.h" | 10 #include "media/cast/net/cast_transport_defines.h" |
12 #include "media/cast/net/rtcp/rtcp_defines.h" | 11 #include "media/cast/net/rtcp/rtcp_defines.h" |
13 #include "media/cast/net/rtcp/rtcp_receiver.h" | 12 #include "media/cast/net/rtcp/rtcp_receiver.h" |
14 #include "media/cast/net/rtcp/rtcp_sender.h" | 13 #include "media/cast/net/rtcp/rtcp_sender.h" |
15 #include "media/cast/net/rtcp/rtcp_utility.h" | 14 #include "media/cast/net/rtcp/rtcp_utility.h" |
16 | 15 |
17 using base::TimeDelta; | 16 using base::TimeDelta; |
18 | 17 |
19 namespace media { | 18 namespace media { |
20 namespace cast { | 19 namespace cast { |
21 | 20 |
22 static const int32 kMaxRttMs = 10000; // 10 seconds. | 21 static const int32 kMaxRttMs = 10000; // 10 seconds. |
23 static const int32 kMaxDelayMs = 2000; // 2 seconds. | |
24 | 22 |
25 class LocalRtcpRttFeedback : public RtcpRttFeedback { | 23 class RtcpMessageHandlerImpl : public RtcpMessageHandler { |
26 public: | 24 public: |
27 explicit LocalRtcpRttFeedback(Rtcp* rtcp) : rtcp_(rtcp) {} | 25 RtcpMessageHandlerImpl(Rtcp* rtcp) |
miu
2014/07/16 00:09:31
explicit
Alpha Left Google
2014/07/17 01:01:45
Done.
| |
28 | 26 : rtcp_(rtcp) {} |
29 virtual void OnReceivedDelaySinceLastReport( | |
30 uint32 receivers_ssrc, uint32 last_report, | |
31 uint32 delay_since_last_report) OVERRIDE { | |
32 rtcp_->OnReceivedDelaySinceLastReport(receivers_ssrc, last_report, | |
33 delay_since_last_report); | |
34 } | |
35 | |
36 private: | |
37 Rtcp* rtcp_; | |
38 }; | |
39 | |
40 class LocalRtcpReceiverFeedback : public RtcpReceiverFeedback { | |
41 public: | |
42 LocalRtcpReceiverFeedback(Rtcp* rtcp, | |
43 scoped_refptr<CastEnvironment> cast_environment) | |
44 : rtcp_(rtcp), cast_environment_(cast_environment) {} | |
45 | 27 |
46 virtual void OnReceivedSenderReport( | 28 virtual void OnReceivedSenderReport( |
47 const RtcpSenderInfo& remote_sender_info) OVERRIDE { | 29 const RtcpSenderInfo& remote_sender_info) OVERRIDE { |
48 rtcp_->OnReceivedNtp(remote_sender_info.ntp_seconds, | 30 rtcp_->OnReceivedNtp(remote_sender_info.ntp_seconds, |
49 remote_sender_info.ntp_fraction); | 31 remote_sender_info.ntp_fraction); |
50 if (remote_sender_info.send_packet_count != 0) { | 32 if (remote_sender_info.send_packet_count != 0) { |
51 rtcp_->OnReceivedLipSyncInfo(remote_sender_info.rtp_timestamp, | 33 rtcp_->OnReceivedLipSyncInfo(remote_sender_info.rtp_timestamp, |
52 remote_sender_info.ntp_seconds, | 34 remote_sender_info.ntp_seconds, |
53 remote_sender_info.ntp_fraction); | 35 remote_sender_info.ntp_fraction); |
54 } | 36 } |
55 } | 37 } |
56 | 38 |
57 virtual void OnReceiverReferenceTimeReport( | 39 virtual void OnReceiverReferenceTimeReport( |
58 const RtcpReceiverReferenceTimeReport& remote_time_report) OVERRIDE { | 40 const RtcpReceiverReferenceTimeReport& remote_time_report) OVERRIDE { |
59 rtcp_->OnReceivedNtp(remote_time_report.ntp_seconds, | 41 rtcp_->OnReceivedNtp(remote_time_report.ntp_seconds, |
60 remote_time_report.ntp_fraction); | 42 remote_time_report.ntp_fraction); |
61 } | 43 } |
62 | 44 |
63 virtual void OnReceivedSendReportRequest() OVERRIDE { | |
64 rtcp_->OnReceivedSendReportRequest(); | |
65 } | |
66 | |
67 virtual void OnReceivedReceiverLog(const RtcpReceiverLogMessage& receiver_log) | 45 virtual void OnReceivedReceiverLog(const RtcpReceiverLogMessage& receiver_log) |
68 OVERRIDE { | 46 OVERRIDE { |
69 rtcp_->OnReceivedReceiverLog(receiver_log); | 47 rtcp_->OnReceivedReceiverLog(receiver_log); |
70 } | 48 } |
71 | 49 |
50 virtual void OnReceivedDelaySinceLastReport( | |
51 uint32 last_report, | |
52 uint32 delay_since_last_report) OVERRIDE { | |
53 rtcp_->OnReceivedDelaySinceLastReport(last_report, delay_since_last_report); | |
54 } | |
55 | |
56 virtual void OnReceivedCastFeedback( | |
57 const RtcpCastMessage& cast_message) OVERRIDE { | |
58 rtcp_->OnReceivedCastFeedback(cast_message); | |
59 } | |
60 | |
72 private: | 61 private: |
73 Rtcp* rtcp_; | 62 Rtcp* rtcp_; |
74 scoped_refptr<CastEnvironment> cast_environment_; | |
75 }; | 63 }; |
76 | 64 |
77 Rtcp::Rtcp(scoped_refptr<CastEnvironment> cast_environment, | 65 Rtcp::Rtcp(const RtcpCastMessageCallback& cast_callback, |
78 RtcpSenderFeedback* sender_feedback, | 66 const RtcpRttCallback& rtt_callback, |
79 CastTransportSender* const transport_sender, | 67 const RtcpLogMessageCallback& log_callback, |
80 PacedPacketSender* paced_packet_sender, | 68 base::TickClock* clock, |
miu
2014/07/16 00:09:31
style/consistency nit: Can you make |clock| be the
Alpha Left Google
2014/07/17 01:01:45
Swapped the members instead. It's much bigger to s
| |
81 RtpReceiverStatistics* rtp_receiver_statistics, RtcpMode rtcp_mode, | 69 PacedPacketSender* packet_sender, |
82 const base::TimeDelta& rtcp_interval, uint32 local_ssrc, | 70 uint32 local_ssrc, |
83 uint32 remote_ssrc, const std::string& c_name, | 71 uint32 remote_ssrc, const std::string& c_name) |
84 EventMediaType event_media_type) | 72 : clock_(clock), |
85 : cast_environment_(cast_environment), | 73 cast_callback_(cast_callback), |
86 transport_sender_(transport_sender), | 74 rtt_callback_(rtt_callback), |
87 rtcp_interval_(rtcp_interval), | 75 log_callback_(log_callback), |
88 rtcp_mode_(rtcp_mode), | |
89 local_ssrc_(local_ssrc), | 76 local_ssrc_(local_ssrc), |
90 remote_ssrc_(remote_ssrc), | 77 remote_ssrc_(remote_ssrc), |
91 c_name_(c_name), | 78 c_name_(c_name), |
92 event_media_type_(event_media_type), | 79 handler_(new RtcpMessageHandlerImpl(this)), |
93 rtp_receiver_statistics_(rtp_receiver_statistics), | 80 rtcp_sender_(new RtcpSender(packet_sender, local_ssrc, c_name)), |
94 rtt_feedback_(new LocalRtcpRttFeedback(this)), | |
95 receiver_feedback_(new LocalRtcpReceiverFeedback(this, cast_environment)), | |
96 rtcp_sender_(new RtcpSender(cast_environment, paced_packet_sender, | |
97 local_ssrc, c_name)), | |
98 last_report_truncated_ntp_(0), | 81 last_report_truncated_ntp_(0), |
99 local_clock_ahead_by_(ClockDriftSmoother::GetDefaultTimeConstant()), | 82 local_clock_ahead_by_(ClockDriftSmoother::GetDefaultTimeConstant()), |
100 lip_sync_rtp_timestamp_(0), | 83 lip_sync_rtp_timestamp_(0), |
101 lip_sync_ntp_timestamp_(0), | 84 lip_sync_ntp_timestamp_(0), |
102 min_rtt_(TimeDelta::FromMilliseconds(kMaxRttMs)), | 85 min_rtt_(TimeDelta::FromMilliseconds(kMaxRttMs)), |
103 number_of_rtt_in_avg_(0) { | 86 number_of_rtt_in_avg_(0) { |
104 rtcp_receiver_.reset(new RtcpReceiver(cast_environment, sender_feedback, | 87 rtcp_receiver_.reset(new RtcpReceiver(handler_.get(), local_ssrc)); |
miu
2014/07/16 00:09:31
Can you move this into the initializer list? ...a
Alpha Left Google
2014/07/17 01:01:45
Done.
| |
105 receiver_feedback_.get(), | |
106 rtt_feedback_.get(), local_ssrc)); | |
107 rtcp_receiver_->SetRemoteSSRC(remote_ssrc); | 88 rtcp_receiver_->SetRemoteSSRC(remote_ssrc); |
89 | |
90 // This value is the same in FrameReceiver. | |
91 rtcp_receiver_->SetCastReceiverEventHistorySize( | |
92 kReceiverRtcpEventHistorySize); | |
108 } | 93 } |
109 | 94 |
110 Rtcp::~Rtcp() {} | 95 Rtcp::~Rtcp() {} |
111 | 96 |
112 // static | 97 bool Rtcp::IncomingRtcpPacket(const uint8* data, size_t length) { |
113 bool Rtcp::IsRtcpPacket(const uint8* packet, size_t length) { | 98 // Check if this is a valid RTCP packet. |
114 DCHECK_GE(length, kMinLengthOfRtcp) << "Invalid RTCP packet"; | 99 if (!RtcpReceiver::IsRtcpPacket(data, length)) { |
miu
2014/07/16 00:09:31
These 5 LOC seem to be redundant, since rtcp_parse
Alpha Left Google
2014/07/17 01:01:45
This checks for Cast specific RTCP payload. While
| |
115 if (length < kMinLengthOfRtcp) return false; | 100 VLOG(1) << "Rtcp@" << this << "::IncomingRtcpPacket() -- " |
101 << "Received an invalid (non-RTCP?) packet."; | |
102 return false; | |
103 } | |
116 | 104 |
117 uint8 packet_type = packet[1]; | 105 // Check if this packet is to us. |
118 if (packet_type >= kPacketTypeLow && | 106 uint32 ssrc_of_sender = RtcpReceiver::GetSsrcOfSender(data, length); |
119 packet_type <= kPacketTypeHigh) { | 107 if (ssrc_of_sender != remote_ssrc_) |
120 return true; | 108 return false; |
121 } | |
122 return false; | |
123 } | |
124 | 109 |
125 // static | 110 // Parse this packet. |
126 uint32 Rtcp::GetSsrcOfSender(const uint8* rtcp_buffer, size_t length) { | 111 RtcpParser rtcp_parser(data, length); |
127 DCHECK_GE(length, kMinLengthOfRtcp) << "Invalid RTCP packet"; | |
128 uint32 ssrc_of_sender; | |
129 base::BigEndianReader big_endian_reader( | |
130 reinterpret_cast<const char*>(rtcp_buffer), length); | |
131 big_endian_reader.Skip(4); // Skip header | |
132 big_endian_reader.ReadU32(&ssrc_of_sender); | |
133 return ssrc_of_sender; | |
134 } | |
135 | |
136 base::TimeTicks Rtcp::TimeToSendNextRtcpReport() { | |
137 if (next_time_to_send_rtcp_.is_null()) { | |
138 UpdateNextTimeToSendRtcp(); | |
139 } | |
140 return next_time_to_send_rtcp_; | |
141 } | |
142 | |
143 void Rtcp::IncomingRtcpPacket(const uint8* rtcp_buffer, size_t length) { | |
144 RtcpParser rtcp_parser(rtcp_buffer, length); | |
145 if (!rtcp_parser.IsValid()) { | 112 if (!rtcp_parser.IsValid()) { |
146 // Silently ignore packet. | 113 // Silently ignore packet. |
147 DLOG(ERROR) << "Received invalid RTCP packet"; | 114 DLOG(ERROR) << "Received invalid RTCP packet"; |
148 return; | 115 return false; |
149 } | 116 } |
150 rtcp_receiver_->IncomingRtcpPacket(&rtcp_parser); | 117 rtcp_receiver_->IncomingRtcpPacket(&rtcp_parser); |
118 return true; | |
151 } | 119 } |
152 | 120 |
153 void Rtcp::SendRtcpFromRtpReceiver( | 121 void Rtcp::SendRtcpFromRtpReceiver( |
154 const RtcpCastMessage* cast_message, | 122 const RtcpCastMessage* cast_message, |
155 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events) { | 123 base::TimeDelta target_delay, |
156 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 124 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, |
125 RtpReceiverStatistics* rtp_receiver_statistics) { | |
157 uint32 packet_type_flags = 0; | 126 uint32 packet_type_flags = 0; |
158 | 127 |
159 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 128 base::TimeTicks now = clock_->NowTicks(); |
160 RtcpReportBlock report_block; | 129 RtcpReportBlock report_block; |
161 RtcpReceiverReferenceTimeReport rrtr; | 130 RtcpReceiverReferenceTimeReport rrtr; |
162 | 131 |
163 // Attach our NTP to all RTCP packets; with this information a "smart" sender | 132 // Attach our NTP to all RTCP packets; with this information a "smart" sender |
164 // can make decisions based on how old the RTCP message is. | 133 // can make decisions based on how old the RTCP message is. |
165 packet_type_flags |= kRtcpRrtr; | 134 packet_type_flags |= kRtcpRrtr; |
166 ConvertTimeTicksToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction); | 135 ConvertTimeTicksToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction); |
167 SaveLastSentNtpTime(now, rrtr.ntp_seconds, rrtr.ntp_fraction); | 136 SaveLastSentNtpTime(now, rrtr.ntp_seconds, rrtr.ntp_fraction); |
168 | 137 |
169 if (cast_message) { | 138 if (cast_message) { |
170 packet_type_flags |= kRtcpCast; | 139 packet_type_flags |= kRtcpCast; |
171 } | 140 } |
172 if (rtcp_events) { | 141 if (rtcp_events) { |
173 packet_type_flags |= kRtcpReceiverLog; | 142 packet_type_flags |= kRtcpReceiverLog; |
174 } | 143 } |
175 if (rtcp_mode_ == kRtcpCompound || now >= next_time_to_send_rtcp_) { | 144 // If RTCP is in compound mode then we always send a RR. |
145 if (rtp_receiver_statistics) { | |
176 packet_type_flags |= kRtcpRr; | 146 packet_type_flags |= kRtcpRr; |
177 | 147 |
178 report_block.remote_ssrc = 0; // Not needed to set send side. | 148 report_block.remote_ssrc = 0; // Not needed to set send side. |
179 report_block.media_ssrc = remote_ssrc_; // SSRC of the RTP packet sender. | 149 report_block.media_ssrc = remote_ssrc_; // SSRC of the RTP packet sender. |
180 if (rtp_receiver_statistics_) { | 150 if (rtp_receiver_statistics) { |
181 rtp_receiver_statistics_->GetStatistics( | 151 rtp_receiver_statistics->GetStatistics( |
182 &report_block.fraction_lost, &report_block.cumulative_lost, | 152 &report_block.fraction_lost, &report_block.cumulative_lost, |
183 &report_block.extended_high_sequence_number, &report_block.jitter); | 153 &report_block.extended_high_sequence_number, &report_block.jitter); |
184 } | 154 } |
185 | 155 |
186 report_block.last_sr = last_report_truncated_ntp_; | 156 report_block.last_sr = last_report_truncated_ntp_; |
187 if (!time_last_report_received_.is_null()) { | 157 if (!time_last_report_received_.is_null()) { |
188 uint32 delay_seconds = 0; | 158 uint32 delay_seconds = 0; |
189 uint32 delay_fraction = 0; | 159 uint32 delay_fraction = 0; |
190 base::TimeDelta delta = now - time_last_report_received_; | 160 base::TimeDelta delta = now - time_last_report_received_; |
191 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, | 161 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, |
192 &delay_fraction); | 162 &delay_fraction); |
193 report_block.delay_since_last_sr = | 163 report_block.delay_since_last_sr = |
194 ConvertToNtpDiff(delay_seconds, delay_fraction); | 164 ConvertToNtpDiff(delay_seconds, delay_fraction); |
195 } else { | 165 } else { |
196 report_block.delay_since_last_sr = 0; | 166 report_block.delay_since_last_sr = 0; |
197 } | 167 } |
198 UpdateNextTimeToSendRtcp(); | |
199 } | 168 } |
200 rtcp_sender_->SendRtcpFromRtpReceiver(packet_type_flags, | 169 rtcp_sender_->SendRtcpFromRtpReceiver(packet_type_flags, |
201 &report_block, | 170 &report_block, |
202 &rrtr, | 171 &rrtr, |
203 cast_message, | 172 cast_message, |
204 rtcp_events, | 173 rtcp_events, |
205 target_delay_); | 174 target_delay); |
206 } | 175 } |
207 | 176 |
208 void Rtcp::SendRtcpFromRtpSender(base::TimeTicks current_time, | 177 void Rtcp::SendRtcpFromRtpSender(base::TimeTicks current_time, |
209 uint32 current_time_as_rtp_timestamp) { | 178 uint32 current_time_as_rtp_timestamp, |
210 DCHECK(transport_sender_); | 179 uint32 send_packet_count, |
180 size_t send_octet_count) { | |
211 uint32 packet_type_flags = kRtcpSr; | 181 uint32 packet_type_flags = kRtcpSr; |
212 uint32 current_ntp_seconds = 0; | 182 uint32 current_ntp_seconds = 0; |
213 uint32 current_ntp_fractions = 0; | 183 uint32 current_ntp_fractions = 0; |
214 ConvertTimeTicksToNtp(current_time, ¤t_ntp_seconds, | 184 ConvertTimeTicksToNtp(current_time, ¤t_ntp_seconds, |
215 ¤t_ntp_fractions); | 185 ¤t_ntp_fractions); |
216 SaveLastSentNtpTime(current_time, current_ntp_seconds, | 186 SaveLastSentNtpTime(current_time, current_ntp_seconds, |
217 current_ntp_fractions); | 187 current_ntp_fractions); |
218 | 188 |
219 RtcpDlrrReportBlock dlrr; | 189 RtcpDlrrReportBlock dlrr; |
220 if (!time_last_report_received_.is_null()) { | 190 if (!time_last_report_received_.is_null()) { |
221 packet_type_flags |= kRtcpDlrr; | 191 packet_type_flags |= kRtcpDlrr; |
222 dlrr.last_rr = last_report_truncated_ntp_; | 192 dlrr.last_rr = last_report_truncated_ntp_; |
223 uint32 delay_seconds = 0; | 193 uint32 delay_seconds = 0; |
224 uint32 delay_fraction = 0; | 194 uint32 delay_fraction = 0; |
225 base::TimeDelta delta = current_time - time_last_report_received_; | 195 base::TimeDelta delta = current_time - time_last_report_received_; |
226 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, | 196 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, |
227 &delay_fraction); | 197 &delay_fraction); |
228 | 198 |
229 dlrr.delay_since_last_rr = ConvertToNtpDiff(delay_seconds, delay_fraction); | 199 dlrr.delay_since_last_rr = ConvertToNtpDiff(delay_seconds, delay_fraction); |
230 } | 200 } |
231 | 201 |
232 transport_sender_->SendRtcpFromRtpSender( | 202 RtcpSenderInfo sender_info; |
233 packet_type_flags, current_ntp_seconds, current_ntp_fractions, | 203 sender_info.ntp_seconds = current_ntp_seconds; |
234 current_time_as_rtp_timestamp, dlrr, local_ssrc_, c_name_); | 204 sender_info.ntp_fraction = current_ntp_fractions; |
235 UpdateNextTimeToSendRtcp(); | 205 sender_info.rtp_timestamp = current_time_as_rtp_timestamp; |
206 sender_info.send_packet_count = send_packet_count; | |
207 sender_info.send_octet_count = send_octet_count; | |
208 | |
209 rtcp_sender_->SendRtcpFromRtpSender(packet_type_flags, sender_info, dlrr); | |
236 } | 210 } |
237 | 211 |
238 void Rtcp::OnReceivedNtp(uint32 ntp_seconds, uint32 ntp_fraction) { | 212 void Rtcp::OnReceivedNtp(uint32 ntp_seconds, uint32 ntp_fraction) { |
239 last_report_truncated_ntp_ = ConvertToNtpDiff(ntp_seconds, ntp_fraction); | 213 last_report_truncated_ntp_ = ConvertToNtpDiff(ntp_seconds, ntp_fraction); |
240 | 214 |
241 const base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 215 const base::TimeTicks now = clock_->NowTicks(); |
242 time_last_report_received_ = now; | 216 time_last_report_received_ = now; |
243 | 217 |
244 // TODO(miu): This clock offset calculation does not account for packet | 218 // TODO(miu): This clock offset calculation does not account for packet |
245 // transit time over the network. End2EndTest.EvilNetwork confirms that this | 219 // transit time over the network. End2EndTest.EvilNetwork confirms that this |
246 // contributes a very significant source of error here. Fix this along with | 220 // contributes a very significant source of error here. Fix this along with |
247 // the RTT clean-up. | 221 // the RTT clean-up. |
248 const base::TimeDelta measured_offset = | 222 const base::TimeDelta measured_offset = |
249 now - ConvertNtpToTimeTicks(ntp_seconds, ntp_fraction); | 223 now - ConvertNtpToTimeTicks(ntp_seconds, ntp_fraction); |
250 local_clock_ahead_by_.Update(now, measured_offset); | 224 local_clock_ahead_by_.Update(now, measured_offset); |
251 if (measured_offset < local_clock_ahead_by_.Current()) { | 225 if (measured_offset < local_clock_ahead_by_.Current()) { |
(...skipping 24 matching lines...) Expand all Loading... | |
276 base::TimeTicks* reference_time) const { | 250 base::TimeTicks* reference_time) const { |
277 if (!lip_sync_ntp_timestamp_) | 251 if (!lip_sync_ntp_timestamp_) |
278 return false; | 252 return false; |
279 | 253 |
280 const base::TimeTicks local_reference_time = | 254 const base::TimeTicks local_reference_time = |
281 ConvertNtpToTimeTicks(static_cast<uint32>(lip_sync_ntp_timestamp_ >> 32), | 255 ConvertNtpToTimeTicks(static_cast<uint32>(lip_sync_ntp_timestamp_ >> 32), |
282 static_cast<uint32>(lip_sync_ntp_timestamp_)) + | 256 static_cast<uint32>(lip_sync_ntp_timestamp_)) + |
283 local_clock_ahead_by_.Current(); | 257 local_clock_ahead_by_.Current(); |
284 | 258 |
285 // Sanity-check: Getting regular lip sync updates? | 259 // Sanity-check: Getting regular lip sync updates? |
286 DCHECK((cast_environment_->Clock()->NowTicks() - local_reference_time) < | 260 DCHECK((clock_->NowTicks() - local_reference_time) < |
287 base::TimeDelta::FromMinutes(1)); | 261 base::TimeDelta::FromMinutes(1)); |
288 | 262 |
289 *rtp_timestamp = lip_sync_rtp_timestamp_; | 263 *rtp_timestamp = lip_sync_rtp_timestamp_; |
290 *reference_time = local_reference_time; | 264 *reference_time = local_reference_time; |
291 return true; | 265 return true; |
292 } | 266 } |
293 | 267 |
294 void Rtcp::OnReceivedSendReportRequest() { | 268 void Rtcp::OnReceivedDelaySinceLastReport(uint32 last_report, |
295 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | |
296 | |
297 // Trigger a new RTCP report at next timer. | |
298 next_time_to_send_rtcp_ = now; | |
299 } | |
300 | |
301 void Rtcp::SetCastReceiverEventHistorySize(size_t size) { | |
302 rtcp_receiver_->SetCastReceiverEventHistorySize(size); | |
303 } | |
304 | |
305 void Rtcp::SetTargetDelay(base::TimeDelta target_delay) { | |
306 DCHECK(target_delay < TimeDelta::FromMilliseconds(kMaxDelayMs)); | |
307 target_delay_ = target_delay; | |
308 } | |
309 | |
310 void Rtcp::OnReceivedDelaySinceLastReport(uint32 receivers_ssrc, | |
311 uint32 last_report, | |
312 uint32 delay_since_last_report) { | 269 uint32 delay_since_last_report) { |
313 RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report); | 270 RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report); |
314 if (it == last_reports_sent_map_.end()) { | 271 if (it == last_reports_sent_map_.end()) { |
315 return; // Feedback on another report. | 272 return; // Feedback on another report. |
316 } | 273 } |
317 | 274 |
318 base::TimeDelta sender_delay = | 275 base::TimeDelta sender_delay = clock_->NowTicks() - it->second; |
319 cast_environment_->Clock()->NowTicks() - it->second; | |
320 UpdateRtt(sender_delay, ConvertFromNtpDiff(delay_since_last_report)); | 276 UpdateRtt(sender_delay, ConvertFromNtpDiff(delay_since_last_report)); |
321 } | 277 } |
322 | 278 |
279 void Rtcp::OnReceivedCastFeedback(const RtcpCastMessage& cast_message) { | |
280 if (cast_callback_.is_null()) | |
281 return; | |
282 cast_callback_.Run(cast_message); | |
283 } | |
284 | |
323 void Rtcp::SaveLastSentNtpTime(const base::TimeTicks& now, | 285 void Rtcp::SaveLastSentNtpTime(const base::TimeTicks& now, |
324 uint32 last_ntp_seconds, | 286 uint32 last_ntp_seconds, |
325 uint32 last_ntp_fraction) { | 287 uint32 last_ntp_fraction) { |
326 // Make sure |now| is always greater than the last element in | 288 // Make sure |now| is always greater than the last element in |
327 // |last_reports_sent_queue_|. | 289 // |last_reports_sent_queue_|. |
328 if (!last_reports_sent_queue_.empty()) | 290 if (!last_reports_sent_queue_.empty()) |
329 DCHECK(now >= last_reports_sent_queue_.back().second); | 291 DCHECK(now >= last_reports_sent_queue_.back().second); |
330 | 292 |
331 uint32 last_report = ConvertToNtpDiff(last_ntp_seconds, last_ntp_fraction); | 293 uint32 last_report = ConvertToNtpDiff(last_ntp_seconds, last_ntp_fraction); |
332 last_reports_sent_map_[last_report] = now; | 294 last_reports_sent_map_[last_report] = now; |
(...skipping 27 matching lines...) Expand all Loading... | |
360 // "average over recent past" mechanism. | 322 // "average over recent past" mechanism. |
361 if (number_of_rtt_in_avg_ != 0) { | 323 if (number_of_rtt_in_avg_ != 0) { |
362 // Integer math equivalent of (ac/(ac+1.0))*avg_rtt_ + (1.0/(ac+1.0))*rtt). | 324 // Integer math equivalent of (ac/(ac+1.0))*avg_rtt_ + (1.0/(ac+1.0))*rtt). |
363 // (TimeDelta only supports math with other TimeDeltas and int64s.) | 325 // (TimeDelta only supports math with other TimeDeltas and int64s.) |
364 avg_rtt_ = (avg_rtt_ * number_of_rtt_in_avg_ + rtt) / | 326 avg_rtt_ = (avg_rtt_ * number_of_rtt_in_avg_ + rtt) / |
365 (number_of_rtt_in_avg_ + 1); | 327 (number_of_rtt_in_avg_ + 1); |
366 } else { | 328 } else { |
367 avg_rtt_ = rtt; | 329 avg_rtt_ = rtt; |
368 } | 330 } |
369 number_of_rtt_in_avg_++; | 331 number_of_rtt_in_avg_++; |
332 | |
333 if (!rtt_callback_.is_null()) | |
334 rtt_callback_.Run(rtt, avg_rtt_, min_rtt_, max_rtt_); | |
370 } | 335 } |
371 | 336 |
372 bool Rtcp::Rtt(base::TimeDelta* rtt, base::TimeDelta* avg_rtt, | 337 bool Rtcp::Rtt(base::TimeDelta* rtt, base::TimeDelta* avg_rtt, |
373 base::TimeDelta* min_rtt, base::TimeDelta* max_rtt) const { | 338 base::TimeDelta* min_rtt, base::TimeDelta* max_rtt) const { |
374 DCHECK(rtt) << "Invalid argument"; | 339 DCHECK(rtt) << "Invalid argument"; |
375 DCHECK(avg_rtt) << "Invalid argument"; | 340 DCHECK(avg_rtt) << "Invalid argument"; |
376 DCHECK(min_rtt) << "Invalid argument"; | 341 DCHECK(min_rtt) << "Invalid argument"; |
377 DCHECK(max_rtt) << "Invalid argument"; | 342 DCHECK(max_rtt) << "Invalid argument"; |
378 | 343 |
379 if (number_of_rtt_in_avg_ == 0) return false; | 344 if (number_of_rtt_in_avg_ == 0) return false; |
380 | 345 |
381 *rtt = rtt_; | 346 *rtt = rtt_; |
382 *avg_rtt = avg_rtt_; | 347 *avg_rtt = avg_rtt_; |
383 *min_rtt = min_rtt_; | 348 *min_rtt = min_rtt_; |
384 *max_rtt = max_rtt_; | 349 *max_rtt = max_rtt_; |
385 return true; | 350 return true; |
386 } | 351 } |
387 | 352 |
388 void Rtcp::UpdateNextTimeToSendRtcp() { | |
389 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | |
390 next_time_to_send_rtcp_ = now + rtcp_interval_; | |
391 } | |
392 | |
393 void Rtcp::OnReceivedReceiverLog(const RtcpReceiverLogMessage& receiver_log) { | 353 void Rtcp::OnReceivedReceiverLog(const RtcpReceiverLogMessage& receiver_log) { |
394 // Add received log messages into our log system. | 354 if (log_callback_.is_null()) |
395 RtcpReceiverLogMessage::const_iterator it = receiver_log.begin(); | 355 return; |
396 for (; it != receiver_log.end(); ++it) { | 356 log_callback_.Run(receiver_log); |
397 uint32 rtp_timestamp = it->rtp_timestamp_; | |
398 | |
399 RtcpReceiverEventLogMessages::const_iterator event_it = | |
400 it->event_log_messages_.begin(); | |
401 for (; event_it != it->event_log_messages_.end(); ++event_it) { | |
402 switch (event_it->type) { | |
403 case PACKET_RECEIVED: | |
404 cast_environment_->Logging()->InsertPacketEvent( | |
405 event_it->event_timestamp, event_it->type, | |
406 event_media_type_, rtp_timestamp, | |
407 kFrameIdUnknown, event_it->packet_id, 0, 0); | |
408 break; | |
409 case FRAME_ACK_SENT: | |
410 case FRAME_DECODED: | |
411 cast_environment_->Logging()->InsertFrameEvent( | |
412 event_it->event_timestamp, event_it->type, event_media_type_, | |
413 rtp_timestamp, kFrameIdUnknown); | |
414 break; | |
415 case FRAME_PLAYOUT: | |
416 cast_environment_->Logging()->InsertFrameEventWithDelay( | |
417 event_it->event_timestamp, event_it->type, event_media_type_, | |
418 rtp_timestamp, kFrameIdUnknown, event_it->delay_delta); | |
419 break; | |
420 default: | |
421 VLOG(2) << "Received log message via RTCP that we did not expect: " | |
422 << static_cast<int>(event_it->type); | |
423 break; | |
424 } | |
425 } | |
426 } | |
427 } | 357 } |
428 | 358 |
429 } // namespace cast | 359 } // namespace cast |
430 } // namespace media | 360 } // namespace media |
OLD | NEW |