OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/cast_transport_sender_impl.h" | 5 #include "media/cast/net/cast_transport_sender_impl.h" |
6 | 6 |
7 #include "base/single_thread_task_runner.h" | 7 #include "base/single_thread_task_runner.h" |
8 #include "base/values.h" | 8 #include "base/values.h" |
9 #include "media/cast/net/cast_transport_config.h" | 9 #include "media/cast/net/cast_transport_config.h" |
10 #include "media/cast/net/cast_transport_defines.h" | 10 #include "media/cast/net/cast_transport_defines.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 int32 min_send_buffer_size = | 45 int32 min_send_buffer_size = |
46 LookupOptionWithDefault(options, kOptionSendBufferMinSize, 0); | 46 LookupOptionWithDefault(options, kOptionSendBufferMinSize, 0); |
47 return std::max(max_burst_size, min_send_buffer_size); | 47 return std::max(max_burst_size, min_send_buffer_size); |
48 } | 48 } |
49 | 49 |
50 } // namespace | 50 } // namespace |
51 | 51 |
52 scoped_ptr<CastTransportSender> CastTransportSender::Create( | 52 scoped_ptr<CastTransportSender> CastTransportSender::Create( |
53 net::NetLog* net_log, | 53 net::NetLog* net_log, |
54 base::TickClock* clock, | 54 base::TickClock* clock, |
| 55 const net::IPEndPoint& local_end_point, |
55 const net::IPEndPoint& remote_end_point, | 56 const net::IPEndPoint& remote_end_point, |
56 scoped_ptr<base::DictionaryValue> options, | 57 scoped_ptr<base::DictionaryValue> options, |
57 const CastTransportStatusCallback& status_callback, | 58 const CastTransportStatusCallback& status_callback, |
58 const BulkRawEventsCallback& raw_events_callback, | 59 const BulkRawEventsCallback& raw_events_callback, |
59 base::TimeDelta raw_events_callback_interval, | 60 base::TimeDelta raw_events_callback_interval, |
| 61 const PacketReceiverCallback& packet_callback, |
60 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) { | 62 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) { |
61 return scoped_ptr<CastTransportSender>( | 63 return scoped_ptr<CastTransportSender>( |
62 new CastTransportSenderImpl(net_log, | 64 new CastTransportSenderImpl(net_log, |
63 clock, | 65 clock, |
| 66 local_end_point, |
64 remote_end_point, | 67 remote_end_point, |
65 options.Pass(), | 68 options.Pass(), |
66 status_callback, | 69 status_callback, |
67 raw_events_callback, | 70 raw_events_callback, |
68 raw_events_callback_interval, | 71 raw_events_callback_interval, |
69 transport_task_runner.get(), | 72 transport_task_runner.get(), |
| 73 packet_callback, |
70 NULL)); | 74 NULL)); |
71 } | 75 } |
72 | 76 |
73 PacketReceiverCallback CastTransportSender::PacketReceiverForTesting() { | 77 PacketReceiverCallback CastTransportSender::PacketReceiverForTesting() { |
74 return PacketReceiverCallback(); | 78 return PacketReceiverCallback(); |
75 } | 79 } |
76 | 80 |
77 CastTransportSenderImpl::CastTransportSenderImpl( | 81 CastTransportSenderImpl::CastTransportSenderImpl( |
78 net::NetLog* net_log, | 82 net::NetLog* net_log, |
79 base::TickClock* clock, | 83 base::TickClock* clock, |
| 84 const net::IPEndPoint& local_end_point, |
80 const net::IPEndPoint& remote_end_point, | 85 const net::IPEndPoint& remote_end_point, |
81 scoped_ptr<base::DictionaryValue> options, | 86 scoped_ptr<base::DictionaryValue> options, |
82 const CastTransportStatusCallback& status_callback, | 87 const CastTransportStatusCallback& status_callback, |
83 const BulkRawEventsCallback& raw_events_callback, | 88 const BulkRawEventsCallback& raw_events_callback, |
84 base::TimeDelta raw_events_callback_interval, | 89 base::TimeDelta raw_events_callback_interval, |
85 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner, | 90 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner, |
| 91 const PacketReceiverCallback& packet_callback, |
86 PacketSender* external_transport) | 92 PacketSender* external_transport) |
87 : clock_(clock), | 93 : clock_(clock), |
88 status_callback_(status_callback), | 94 status_callback_(status_callback), |
89 transport_task_runner_(transport_task_runner), | 95 transport_task_runner_(transport_task_runner), |
90 transport_( | 96 transport_( |
91 external_transport ? | 97 external_transport ? |
92 NULL : | 98 NULL : |
93 new UdpTransport(net_log, | 99 new UdpTransport(net_log, |
94 transport_task_runner, | 100 transport_task_runner, |
95 net::IPEndPoint(), | 101 local_end_point, |
96 remote_end_point, | 102 remote_end_point, |
97 GetTransportSendBufferSize(*options), | 103 GetTransportSendBufferSize(*options), |
98 status_callback)), | 104 status_callback)), |
99 pacer_(LookupOptionWithDefault(*options, | 105 pacer_(LookupOptionWithDefault(*options, |
100 kOptionPacerTargetBurstSize, | 106 kOptionPacerTargetBurstSize, |
101 kTargetBurstSize), | 107 kTargetBurstSize), |
102 LookupOptionWithDefault(*options, | 108 LookupOptionWithDefault(*options, |
103 kOptionPacerMaxBurstSize, | 109 kOptionPacerMaxBurstSize, |
104 kMaxBurstSize), | 110 kMaxBurstSize), |
105 clock, | 111 clock, |
106 &logging_, | 112 &logging_, |
107 external_transport ? external_transport : transport_.get(), | 113 external_transport ? external_transport : transport_.get(), |
108 transport_task_runner), | 114 transport_task_runner), |
109 raw_events_callback_(raw_events_callback), | 115 raw_events_callback_(raw_events_callback), |
110 raw_events_callback_interval_(raw_events_callback_interval), | 116 raw_events_callback_interval_(raw_events_callback_interval), |
111 last_byte_acked_for_audio_(0), | 117 last_byte_acked_for_audio_(0), |
| 118 packet_callback_(packet_callback), |
112 weak_factory_(this) { | 119 weak_factory_(this) { |
113 DCHECK(clock_); | 120 DCHECK(clock_); |
114 if (!raw_events_callback_.is_null()) { | 121 if (!raw_events_callback_.is_null()) { |
115 DCHECK(raw_events_callback_interval > base::TimeDelta()); | 122 DCHECK(raw_events_callback_interval > base::TimeDelta()); |
116 event_subscriber_.reset(new SimpleEventSubscriber); | 123 event_subscriber_.reset(new SimpleEventSubscriber); |
117 logging_.AddRawEventSubscriber(event_subscriber_.get()); | 124 logging_.AddRawEventSubscriber(event_subscriber_.get()); |
118 transport_task_runner->PostDelayedTask( | 125 transport_task_runner->PostDelayedTask( |
119 FROM_HERE, | 126 FROM_HERE, |
120 base::Bind(&CastTransportSenderImpl::SendRawEvents, | 127 base::Bind(&CastTransportSenderImpl::SendRawEvents, |
121 weak_factory_.GetWeakPtr()), | 128 weak_factory_.GetWeakPtr()), |
122 raw_events_callback_interval); | 129 raw_events_callback_interval); |
123 } | 130 } |
124 if (transport_) { | 131 if (transport_) { |
125 if (options->HasKey(kOptionDscp)) { | 132 if (options->HasKey(kOptionDscp)) { |
126 // The default DSCP value for cast is AF41. Which gives it a higher | 133 // The default DSCP value for cast is AF41. Which gives it a higher |
127 // priority over other traffic. | 134 // priority over other traffic. |
128 transport_->SetDscp(net::DSCP_AF41); | 135 transport_->SetDscp(net::DSCP_AF41); |
129 } | 136 } |
130 transport_->StartReceiving( | 137 transport_->StartReceiving( |
131 base::Bind(&CastTransportSenderImpl::OnReceivedPacket, | 138 base::Bind(&CastTransportSenderImpl::OnReceivedPacket, |
132 weak_factory_.GetWeakPtr())); | 139 base::Unretained(this))); |
133 int wifi_options = 0; | 140 int wifi_options = 0; |
134 if (options->HasKey(kOptionWifiDisableScan)) { | 141 if (options->HasKey(kOptionWifiDisableScan)) { |
135 wifi_options |= net::WIFI_OPTIONS_DISABLE_SCAN; | 142 wifi_options |= net::WIFI_OPTIONS_DISABLE_SCAN; |
136 } | 143 } |
137 if (options->HasKey(kOptionWifiMediaStreamingMode)) { | 144 if (options->HasKey(kOptionWifiMediaStreamingMode)) { |
138 wifi_options |= net::WIFI_OPTIONS_MEDIA_STREAMING_MODE; | 145 wifi_options |= net::WIFI_OPTIONS_MEDIA_STREAMING_MODE; |
139 } | 146 } |
140 if (wifi_options) { | 147 if (wifi_options) { |
141 wifi_options_autoreset_ = net::SetWifiOptions(wifi_options); | 148 wifi_options_autoreset_ = net::SetWifiOptions(wifi_options); |
142 } | 149 } |
143 } | 150 } |
144 } | 151 } |
145 | 152 |
146 CastTransportSenderImpl::~CastTransportSenderImpl() { | 153 CastTransportSenderImpl::~CastTransportSenderImpl() { |
| 154 if (transport_) { |
| 155 transport_->StopReceiving(); |
| 156 } |
147 if (event_subscriber_.get()) | 157 if (event_subscriber_.get()) |
148 logging_.RemoveRawEventSubscriber(event_subscriber_.get()); | 158 logging_.RemoveRawEventSubscriber(event_subscriber_.get()); |
149 } | 159 } |
150 | 160 |
151 void CastTransportSenderImpl::InitializeAudio( | 161 void CastTransportSenderImpl::InitializeAudio( |
152 const CastTransportRtpConfig& config, | 162 const CastTransportRtpConfig& config, |
153 const RtcpCastMessageCallback& cast_message_cb, | 163 const RtcpCastMessageCallback& cast_message_cb, |
154 const RtcpRttCallback& rtt_cb) { | 164 const RtcpRttCallback& rtt_cb) { |
155 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty()) | 165 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty()) |
156 << "Unsafe to send audio with encryption DISABLED."; | 166 << "Unsafe to send audio with encryption DISABLED."; |
(...skipping 19 matching lines...) Expand all Loading... |
176 weak_factory_.GetWeakPtr(), config.ssrc, | 186 weak_factory_.GetWeakPtr(), config.ssrc, |
177 cast_message_cb), | 187 cast_message_cb), |
178 rtt_cb, | 188 rtt_cb, |
179 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage, | 189 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage, |
180 weak_factory_.GetWeakPtr(), AUDIO_EVENT), | 190 weak_factory_.GetWeakPtr(), AUDIO_EVENT), |
181 clock_, | 191 clock_, |
182 &pacer_, | 192 &pacer_, |
183 config.ssrc, | 193 config.ssrc, |
184 config.feedback_ssrc)); | 194 config.feedback_ssrc)); |
185 pacer_.RegisterAudioSsrc(config.ssrc); | 195 pacer_.RegisterAudioSsrc(config.ssrc); |
| 196 AddValidSsrc(config.feedback_ssrc); |
186 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED); | 197 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED); |
187 } | 198 } |
188 | 199 |
189 void CastTransportSenderImpl::InitializeVideo( | 200 void CastTransportSenderImpl::InitializeVideo( |
190 const CastTransportRtpConfig& config, | 201 const CastTransportRtpConfig& config, |
191 const RtcpCastMessageCallback& cast_message_cb, | 202 const RtcpCastMessageCallback& cast_message_cb, |
192 const RtcpRttCallback& rtt_cb) { | 203 const RtcpRttCallback& rtt_cb) { |
193 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty()) | 204 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty()) |
194 << "Unsafe to send video with encryption DISABLED."; | 205 << "Unsafe to send video with encryption DISABLED."; |
195 if (!video_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) { | 206 if (!video_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) { |
(...skipping 13 matching lines...) Expand all Loading... |
209 weak_factory_.GetWeakPtr(), config.ssrc, | 220 weak_factory_.GetWeakPtr(), config.ssrc, |
210 cast_message_cb), | 221 cast_message_cb), |
211 rtt_cb, | 222 rtt_cb, |
212 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage, | 223 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage, |
213 weak_factory_.GetWeakPtr(), VIDEO_EVENT), | 224 weak_factory_.GetWeakPtr(), VIDEO_EVENT), |
214 clock_, | 225 clock_, |
215 &pacer_, | 226 &pacer_, |
216 config.ssrc, | 227 config.ssrc, |
217 config.feedback_ssrc)); | 228 config.feedback_ssrc)); |
218 pacer_.RegisterVideoSsrc(config.ssrc); | 229 pacer_.RegisterVideoSsrc(config.ssrc); |
| 230 AddValidSsrc(config.feedback_ssrc); |
219 status_callback_.Run(TRANSPORT_VIDEO_INITIALIZED); | 231 status_callback_.Run(TRANSPORT_VIDEO_INITIALIZED); |
220 } | 232 } |
221 | 233 |
222 namespace { | 234 namespace { |
223 void EncryptAndSendFrame(const EncodedFrame& frame, | 235 void EncryptAndSendFrame(const EncodedFrame& frame, |
224 TransportEncryptionHandler* encryptor, | 236 TransportEncryptionHandler* encryptor, |
225 RtpSender* sender) { | 237 RtpSender* sender) { |
226 if (encryptor->is_activated()) { | 238 if (encryptor->is_activated()) { |
227 EncodedFrame encrypted_frame; | 239 EncodedFrame encrypted_frame; |
228 frame.CopyMetadataTo(&encrypted_frame); | 240 frame.CopyMetadataTo(&encrypted_frame); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 } else if (video_sender_ && ssrc == video_sender_->ssrc()) { | 319 } else if (video_sender_ && ssrc == video_sender_->ssrc()) { |
308 video_sender_->ResendPackets(missing_packets, | 320 video_sender_->ResendPackets(missing_packets, |
309 cancel_rtx_if_not_in_list, | 321 cancel_rtx_if_not_in_list, |
310 dedup_info); | 322 dedup_info); |
311 } else { | 323 } else { |
312 NOTREACHED() << "Invalid request for retransmission."; | 324 NOTREACHED() << "Invalid request for retransmission."; |
313 } | 325 } |
314 } | 326 } |
315 | 327 |
316 PacketReceiverCallback CastTransportSenderImpl::PacketReceiverForTesting() { | 328 PacketReceiverCallback CastTransportSenderImpl::PacketReceiverForTesting() { |
317 return base::Bind(&CastTransportSenderImpl::OnReceivedPacket, | 329 return base::Bind( |
318 weak_factory_.GetWeakPtr()); | 330 base::IgnoreResult(&CastTransportSenderImpl::OnReceivedPacket), |
| 331 weak_factory_.GetWeakPtr()); |
319 } | 332 } |
320 | 333 |
321 void CastTransportSenderImpl::SendRawEvents() { | 334 void CastTransportSenderImpl::SendRawEvents() { |
322 DCHECK(event_subscriber_.get()); | 335 DCHECK(event_subscriber_.get()); |
323 DCHECK(!raw_events_callback_.is_null()); | 336 DCHECK(!raw_events_callback_.is_null()); |
324 std::vector<PacketEvent> packet_events; | 337 std::vector<PacketEvent> packet_events; |
325 std::vector<FrameEvent> frame_events; | 338 std::vector<FrameEvent> frame_events; |
326 event_subscriber_->GetPacketEventsAndReset(&packet_events); | 339 event_subscriber_->GetPacketEventsAndReset(&packet_events); |
327 event_subscriber_->GetFrameEventsAndReset(&frame_events); | 340 event_subscriber_->GetFrameEventsAndReset(&frame_events); |
328 raw_events_callback_.Run(packet_events, frame_events); | 341 raw_events_callback_.Run(packet_events, frame_events); |
329 | 342 |
330 transport_task_runner_->PostDelayedTask( | 343 transport_task_runner_->PostDelayedTask( |
331 FROM_HERE, | 344 FROM_HERE, |
332 base::Bind(&CastTransportSenderImpl::SendRawEvents, | 345 base::Bind(&CastTransportSenderImpl::SendRawEvents, |
333 weak_factory_.GetWeakPtr()), | 346 weak_factory_.GetWeakPtr()), |
334 raw_events_callback_interval_); | 347 raw_events_callback_interval_); |
335 } | 348 } |
336 | 349 |
337 void CastTransportSenderImpl::OnReceivedPacket(scoped_ptr<Packet> packet) { | 350 bool CastTransportSenderImpl::OnReceivedPacket(scoped_ptr<Packet> packet) { |
| 351 const uint8_t* const data = &packet->front(); |
| 352 const size_t length = packet->size(); |
| 353 uint32 ssrc; |
| 354 if (Rtcp::IsRtcpPacket(data, length)) { |
| 355 ssrc = Rtcp::GetSsrcOfSender(data, length); |
| 356 } else if (!RtpParser::ParseSsrc(data, length, &ssrc)) { |
| 357 VLOG(1) << "Invalid RTP packet."; |
| 358 return false; |
| 359 } |
| 360 if (valid_ssrcs_.find(ssrc) == valid_ssrcs_.end()) { |
| 361 VLOG(1) << "Stale packet received."; |
| 362 return false; |
| 363 } |
| 364 |
338 if (audio_rtcp_session_ && | 365 if (audio_rtcp_session_ && |
339 audio_rtcp_session_->IncomingRtcpPacket(&packet->front(), | 366 audio_rtcp_session_->IncomingRtcpPacket(data, length)) { |
340 packet->size())) { | 367 return true; |
341 return; | |
342 } | 368 } |
343 if (video_rtcp_session_ && | 369 if (video_rtcp_session_ && |
344 video_rtcp_session_->IncomingRtcpPacket(&packet->front(), | 370 video_rtcp_session_->IncomingRtcpPacket(data, length)) { |
345 packet->size())) { | 371 return true; |
346 return; | |
347 } | 372 } |
348 VLOG(1) << "Stale packet received."; | 373 if (packet_callback_.is_null()) { |
| 374 VLOG(1) << "Stale packet received."; |
| 375 return false; |
| 376 } |
| 377 packet_callback_.Run(packet.Pass()); |
| 378 return true; |
349 } | 379 } |
350 | 380 |
351 void CastTransportSenderImpl::OnReceivedLogMessage( | 381 void CastTransportSenderImpl::OnReceivedLogMessage( |
352 EventMediaType media_type, | 382 EventMediaType media_type, |
353 const RtcpReceiverLogMessage& log) { | 383 const RtcpReceiverLogMessage& log) { |
354 // Add received log messages into our log system. | 384 // Add received log messages into our log system. |
355 RtcpReceiverLogMessage::const_iterator it = log.begin(); | 385 RtcpReceiverLogMessage::const_iterator it = log.begin(); |
356 for (; it != log.end(); ++it) { | 386 for (; it != log.end(); ++it) { |
357 uint32 rtp_timestamp = it->rtp_timestamp_; | 387 uint32 rtp_timestamp = it->rtp_timestamp_; |
358 | 388 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 // 1. Specifies that retransmissions for packets not listed in the set are | 445 // 1. Specifies that retransmissions for packets not listed in the set are |
416 // cancelled. | 446 // cancelled. |
417 // 2. Specifies a deduplication window. For video this would be the most | 447 // 2. Specifies a deduplication window. For video this would be the most |
418 // recent RTT. For audio there is no deduplication. | 448 // recent RTT. For audio there is no deduplication. |
419 ResendPackets(ssrc, | 449 ResendPackets(ssrc, |
420 cast_message.missing_frames_and_packets, | 450 cast_message.missing_frames_and_packets, |
421 true, | 451 true, |
422 dedup_info); | 452 dedup_info); |
423 } | 453 } |
424 | 454 |
| 455 void CastTransportSenderImpl::AddValidSsrc(uint32 ssrc) { |
| 456 valid_ssrcs_.insert(ssrc); |
| 457 } |
| 458 |
| 459 void CastTransportSenderImpl::SendRtcpFromRtpReceiver( |
| 460 uint32 ssrc, |
| 461 uint32 sender_ssrc, |
| 462 const RtcpTimeData& time_data, |
| 463 const RtcpCastMessage* cast_message, |
| 464 base::TimeDelta target_delay, |
| 465 const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events, |
| 466 const RtpReceiverStatistics* rtp_receiver_statistics) { |
| 467 const Rtcp rtcp(RtcpCastMessageCallback(), |
| 468 RtcpRttCallback(), |
| 469 RtcpLogMessageCallback(), |
| 470 clock_, |
| 471 &pacer_, |
| 472 ssrc, |
| 473 sender_ssrc); |
| 474 rtcp.SendRtcpFromRtpReceiver(time_data, |
| 475 cast_message, |
| 476 target_delay, |
| 477 rtcp_events, |
| 478 rtp_receiver_statistics); |
| 479 } |
| 480 |
425 } // namespace cast | 481 } // namespace cast |
426 } // namespace media | 482 } // namespace media |
OLD | NEW |