Chromium Code Reviews| 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 <algorithm> | |
| 8 #include <string> | |
| 9 | |
| 7 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
| 8 #include "base/values.h" | 11 #include "base/values.h" |
| 9 #include "media/cast/net/cast_transport_defines.h" | 12 #include "media/cast/net/cast_transport_defines.h" |
| 13 #include "media/cast/net/rtcp/receiver_rtcp_session.h" | |
| 14 #include "media/cast/net/rtcp/sender_rtcp_session.h" | |
| 10 #include "media/cast/net/udp_transport.h" | 15 #include "media/cast/net/udp_transport.h" |
| 11 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
| 12 #include "net/base/network_interfaces.h" | 17 #include "net/base/network_interfaces.h" |
| 13 | 18 |
| 14 namespace media { | 19 namespace media { |
| 15 namespace cast { | 20 namespace cast { |
| 16 | 21 |
| 17 namespace { | 22 namespace { |
| 18 | 23 |
| 19 // See header file for what these mean. | 24 // See header file for what these mean. |
| 20 const char kOptionDscp[] = "DSCP"; | 25 const char kOptionDscp[] = "DSCP"; |
| 21 #if defined(OS_WIN) | 26 #if defined(OS_WIN) |
| 22 const char kOptionDisableNonBlockingIO[] = "disable_non_blocking_io"; | 27 const char kOptionDisableNonBlockingIO[] = "disable_non_blocking_io"; |
| 23 #endif | 28 #endif |
| 24 const char kOptionPacerTargetBurstSize[] = "pacer_target_burst_size"; | 29 const char kOptionPacerTargetBurstSize[] = "pacer_target_burst_size"; |
| 25 const char kOptionPacerMaxBurstSize[] = "pacer_max_burst_size"; | 30 const char kOptionPacerMaxBurstSize[] = "pacer_max_burst_size"; |
| 26 const char kOptionSendBufferMinSize[] = "send_buffer_min_size"; | 31 const char kOptionSendBufferMinSize[] = "send_buffer_min_size"; |
| 27 const char kOptionWifiDisableScan[] = "disable_wifi_scan"; | 32 const char kOptionWifiDisableScan[] = "disable_wifi_scan"; |
| 28 const char kOptionWifiMediaStreamingMode[] = "media_streaming_mode"; | 33 const char kOptionWifiMediaStreamingMode[] = "media_streaming_mode"; |
| 29 | 34 |
| 30 int LookupOptionWithDefault(const base::DictionaryValue& options, | 35 int LookupOptionWithDefault(const base::DictionaryValue& options, |
| 31 const std::string& path, | 36 const std::string& path, |
| 32 int default_value) { | 37 int default_value) { |
| 33 int ret; | 38 int ret; |
| 34 if (options.GetInteger(path, &ret)) { | 39 if (options.GetInteger(path, &ret)) { |
| 35 return ret; | 40 return ret; |
| 36 } else { | 41 } else { |
| 37 return default_value; | 42 return default_value; |
| 38 } | 43 } |
| 39 }; | 44 } |
| 40 | 45 |
| 41 int32 GetTransportSendBufferSize(const base::DictionaryValue& options) { | 46 int32 GetTransportSendBufferSize(const base::DictionaryValue& options) { |
| 42 // Socket send buffer size needs to be at least greater than one burst | 47 // Socket send buffer size needs to be at least greater than one burst |
| 43 // size. | 48 // size. |
| 44 int32 max_burst_size = | 49 int32 max_burst_size = |
| 45 LookupOptionWithDefault(options, kOptionPacerMaxBurstSize, | 50 LookupOptionWithDefault(options, kOptionPacerMaxBurstSize, |
| 46 kMaxBurstSize) * kMaxIpPacketSize; | 51 kMaxBurstSize) * kMaxIpPacketSize; |
| 47 int32 min_send_buffer_size = | 52 int32 min_send_buffer_size = |
| 48 LookupOptionWithDefault(options, kOptionSendBufferMinSize, 0); | 53 LookupOptionWithDefault(options, kOptionSendBufferMinSize, 0); |
| 49 return std::max(max_burst_size, min_send_buffer_size); | 54 return std::max(max_burst_size, min_send_buffer_size); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 176 // Audio packets have a higher priority. | 181 // Audio packets have a higher priority. |
| 177 pacer_.RegisterAudioSsrc(config.ssrc); | 182 pacer_.RegisterAudioSsrc(config.ssrc); |
| 178 pacer_.RegisterPrioritySsrc(config.ssrc); | 183 pacer_.RegisterPrioritySsrc(config.ssrc); |
| 179 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED); | 184 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED); |
| 180 } else { | 185 } else { |
| 181 audio_sender_.reset(); | 186 audio_sender_.reset(); |
| 182 status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED); | 187 status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED); |
| 183 return; | 188 return; |
| 184 } | 189 } |
| 185 | 190 |
| 186 audio_rtcp_session_.reset( | 191 audio_rtcp_session_.reset(new SenderRtcpSession( |
| 187 new Rtcp(base::Bind(&CastTransportSenderImpl::OnReceivedCastMessage, | 192 base::Bind(&CastTransportSenderImpl::OnReceivedCastMessage, |
| 188 weak_factory_.GetWeakPtr(), config.ssrc, | 193 weak_factory_.GetWeakPtr(), config.ssrc, cast_message_cb), |
| 189 cast_message_cb), | 194 rtt_cb, base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage, |
| 190 rtt_cb, | 195 weak_factory_.GetWeakPtr(), AUDIO_EVENT), |
| 191 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage, | 196 clock_, &pacer_, config.ssrc, config.feedback_ssrc)); |
| 192 weak_factory_.GetWeakPtr(), AUDIO_EVENT), | |
| 193 clock_, | |
| 194 &pacer_, | |
| 195 config.ssrc, | |
| 196 config.feedback_ssrc)); | |
| 197 pacer_.RegisterAudioSsrc(config.ssrc); | 197 pacer_.RegisterAudioSsrc(config.ssrc); |
| 198 AddValidSsrc(config.feedback_ssrc); | 198 AddValidSsrc(config.feedback_ssrc); |
| 199 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED); | 199 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED); |
| 200 } | 200 } |
| 201 | 201 |
| 202 void CastTransportSenderImpl::InitializeVideo( | 202 void CastTransportSenderImpl::InitializeVideo( |
| 203 const CastTransportRtpConfig& config, | 203 const CastTransportRtpConfig& config, |
| 204 const RtcpCastMessageCallback& cast_message_cb, | 204 const RtcpCastMessageCallback& cast_message_cb, |
| 205 const RtcpRttCallback& rtt_cb) { | 205 const RtcpRttCallback& rtt_cb) { |
| 206 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty()) | 206 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty()) |
| 207 << "Unsafe to send video with encryption DISABLED."; | 207 << "Unsafe to send video with encryption DISABLED."; |
| 208 if (!video_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) { | 208 if (!video_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) { |
| 209 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED); | 209 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED); |
| 210 return; | 210 return; |
| 211 } | 211 } |
| 212 | 212 |
| 213 video_sender_.reset(new RtpSender(transport_task_runner_, &pacer_)); | 213 video_sender_.reset(new RtpSender(transport_task_runner_, &pacer_)); |
| 214 if (!video_sender_->Initialize(config)) { | 214 if (!video_sender_->Initialize(config)) { |
| 215 video_sender_.reset(); | 215 video_sender_.reset(); |
| 216 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED); | 216 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED); |
| 217 return; | 217 return; |
| 218 } | 218 } |
| 219 | 219 |
| 220 video_rtcp_session_.reset( | 220 video_rtcp_session_.reset(new SenderRtcpSession( |
| 221 new Rtcp(base::Bind(&CastTransportSenderImpl::OnReceivedCastMessage, | 221 base::Bind(&CastTransportSenderImpl::OnReceivedCastMessage, |
| 222 weak_factory_.GetWeakPtr(), config.ssrc, | 222 weak_factory_.GetWeakPtr(), config.ssrc, cast_message_cb), |
| 223 cast_message_cb), | 223 rtt_cb, base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage, |
| 224 rtt_cb, | 224 weak_factory_.GetWeakPtr(), VIDEO_EVENT), |
| 225 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage, | 225 clock_, &pacer_, config.ssrc, config.feedback_ssrc)); |
| 226 weak_factory_.GetWeakPtr(), VIDEO_EVENT), | |
| 227 clock_, | |
| 228 &pacer_, | |
| 229 config.ssrc, | |
| 230 config.feedback_ssrc)); | |
| 231 pacer_.RegisterVideoSsrc(config.ssrc); | 226 pacer_.RegisterVideoSsrc(config.ssrc); |
| 232 AddValidSsrc(config.feedback_ssrc); | 227 AddValidSsrc(config.feedback_ssrc); |
| 233 status_callback_.Run(TRANSPORT_VIDEO_INITIALIZED); | 228 status_callback_.Run(TRANSPORT_VIDEO_INITIALIZED); |
| 234 } | 229 } |
| 235 | 230 |
| 236 namespace { | 231 namespace { |
| 237 void EncryptAndSendFrame(const EncodedFrame& frame, | 232 void EncryptAndSendFrame(const EncodedFrame& frame, |
| 238 TransportEncryptionHandler* encryptor, | 233 TransportEncryptionHandler* encryptor, |
| 239 RtpSender* sender) { | 234 RtpSender* sender) { |
| 240 // TODO(miu): We probably shouldn't attempt to send an empty frame, but this | 235 // TODO(miu): We probably shouldn't attempt to send an empty frame, but this |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 263 } else { | 258 } else { |
| 264 NOTREACHED() << "Invalid InsertFrame call."; | 259 NOTREACHED() << "Invalid InsertFrame call."; |
| 265 } | 260 } |
| 266 } | 261 } |
| 267 | 262 |
| 268 void CastTransportSenderImpl::SendSenderReport( | 263 void CastTransportSenderImpl::SendSenderReport( |
| 269 uint32 ssrc, | 264 uint32 ssrc, |
| 270 base::TimeTicks current_time, | 265 base::TimeTicks current_time, |
| 271 RtpTimeTicks current_time_as_rtp_timestamp) { | 266 RtpTimeTicks current_time_as_rtp_timestamp) { |
| 272 if (audio_sender_ && ssrc == audio_sender_->ssrc()) { | 267 if (audio_sender_ && ssrc == audio_sender_->ssrc()) { |
| 273 audio_rtcp_session_->SendRtcpFromRtpSender( | 268 audio_rtcp_session_->SendRtcpReport( |
| 274 current_time, current_time_as_rtp_timestamp, | 269 current_time, current_time_as_rtp_timestamp, |
| 275 audio_sender_->send_packet_count(), audio_sender_->send_octet_count()); | 270 audio_sender_->send_packet_count(), audio_sender_->send_octet_count()); |
| 276 } else if (video_sender_ && ssrc == video_sender_->ssrc()) { | 271 } else if (video_sender_ && ssrc == video_sender_->ssrc()) { |
| 277 video_rtcp_session_->SendRtcpFromRtpSender( | 272 video_rtcp_session_->SendRtcpReport( |
| 278 current_time, current_time_as_rtp_timestamp, | 273 current_time, current_time_as_rtp_timestamp, |
| 279 video_sender_->send_packet_count(), video_sender_->send_octet_count()); | 274 video_sender_->send_packet_count(), video_sender_->send_octet_count()); |
| 280 } else { | 275 } else { |
| 281 NOTREACHED() << "Invalid request for sending RTCP packet."; | 276 NOTREACHED() << "Invalid request for sending RTCP packet."; |
| 282 } | 277 } |
| 283 } | 278 } |
| 284 | 279 |
| 285 void CastTransportSenderImpl::CancelSendingFrames( | 280 void CastTransportSenderImpl::CancelSendingFrames( |
| 286 uint32 ssrc, | 281 uint32 ssrc, |
| 287 const std::vector<uint32>& frame_ids) { | 282 const std::vector<uint32>& frame_ids) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 FROM_HERE, | 347 FROM_HERE, |
| 353 base::Bind(&CastTransportSenderImpl::SendRawEvents, | 348 base::Bind(&CastTransportSenderImpl::SendRawEvents, |
| 354 weak_factory_.GetWeakPtr()), | 349 weak_factory_.GetWeakPtr()), |
| 355 raw_events_callback_interval_); | 350 raw_events_callback_interval_); |
| 356 } | 351 } |
| 357 | 352 |
| 358 bool CastTransportSenderImpl::OnReceivedPacket(scoped_ptr<Packet> packet) { | 353 bool CastTransportSenderImpl::OnReceivedPacket(scoped_ptr<Packet> packet) { |
| 359 const uint8_t* const data = &packet->front(); | 354 const uint8_t* const data = &packet->front(); |
| 360 const size_t length = packet->size(); | 355 const size_t length = packet->size(); |
| 361 uint32 ssrc; | 356 uint32 ssrc; |
| 362 if (Rtcp::IsRtcpPacket(data, length)) { | 357 if (IsRtcpPacket(data, length)) { |
| 363 ssrc = Rtcp::GetSsrcOfSender(data, length); | 358 ssrc = GetSsrcOfSender(data, length); |
| 364 } else if (!RtpParser::ParseSsrc(data, length, &ssrc)) { | 359 } else if (!RtpParser::ParseSsrc(data, length, &ssrc)) { |
| 365 VLOG(1) << "Invalid RTP packet."; | 360 VLOG(1) << "Invalid RTP packet."; |
| 366 return false; | 361 return false; |
| 367 } | 362 } |
| 368 if (valid_ssrcs_.find(ssrc) == valid_ssrcs_.end()) { | 363 if (valid_ssrcs_.find(ssrc) == valid_ssrcs_.end()) { |
| 369 VLOG(1) << "Stale packet received."; | 364 VLOG(1) << "Stale packet received."; |
| 370 return false; | 365 return false; |
| 371 } | 366 } |
| 372 | 367 |
| 373 if (audio_rtcp_session_ && | 368 if (audio_rtcp_session_ && |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 } | 465 } |
| 471 | 466 |
| 472 void CastTransportSenderImpl::SendRtcpFromRtpReceiver( | 467 void CastTransportSenderImpl::SendRtcpFromRtpReceiver( |
| 473 uint32 ssrc, | 468 uint32 ssrc, |
| 474 uint32 sender_ssrc, | 469 uint32 sender_ssrc, |
| 475 const RtcpTimeData& time_data, | 470 const RtcpTimeData& time_data, |
| 476 const RtcpCastMessage* cast_message, | 471 const RtcpCastMessage* cast_message, |
| 477 base::TimeDelta target_delay, | 472 base::TimeDelta target_delay, |
| 478 const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events, | 473 const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events, |
| 479 const RtpReceiverStatistics* rtp_receiver_statistics) { | 474 const RtpReceiverStatistics* rtp_receiver_statistics) { |
| 480 const Rtcp rtcp(RtcpCastMessageCallback(), | 475 const ReceiverRtcpSession rtcp(clock_, &pacer_, ssrc, sender_ssrc); |
| 481 RtcpRttCallback(), | 476 rtcp.SendRtcpReport(time_data, cast_message, target_delay, rtcp_events, |
|
miu
2015/12/12 00:53:25
Huh. Interesting that this was in the CastTranspo
Irfan
2015/12/12 01:07:37
will do because this is indeed confusing code, but
| |
| 482 RtcpLogMessageCallback(), | 477 rtp_receiver_statistics); |
| 483 clock_, | |
| 484 &pacer_, | |
| 485 ssrc, | |
| 486 sender_ssrc); | |
| 487 rtcp.SendRtcpFromRtpReceiver(time_data, | |
| 488 cast_message, | |
| 489 target_delay, | |
| 490 rtcp_events, | |
| 491 rtp_receiver_statistics); | |
| 492 } | 478 } |
| 493 | 479 |
| 494 } // namespace cast | 480 } // namespace cast |
| 495 } // namespace media | 481 } // namespace media |
| OLD | NEW |