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