Index: chrome/browser/media/cast_transport_host_filter.cc |
diff --git a/chrome/browser/media/cast_transport_host_filter.cc b/chrome/browser/media/cast_transport_host_filter.cc |
index 0e6b600a7ed1b7f9c735b06e022d916ad332aa40..14d55cef0d8a87cc2ea66f19c85b0827341781a3 100644 |
--- a/chrome/browser/media/cast_transport_host_filter.cc |
+++ b/chrome/browser/media/cast_transport_host_filter.cc |
@@ -10,14 +10,92 @@ |
#include "components/net_log/chrome_net_log.h" |
#include "content/public/browser/power_save_blocker.h" |
#include "media/cast/net/cast_transport_sender.h" |
+#include "net/base/network_interfaces.h" |
namespace { |
// How often to send raw events. |
const int kSendRawEventsIntervalSecs = 1; |
+// Options for UdpTransport. |
+const char kOptionDscp[] = "DSCP"; |
+#if defined(OS_WIN) |
+const char kOptionDisableNonBlockingIO[] = "disable_non_blocking_io"; |
+#endif |
+const char kOptionSendBufferMinSize[] = "send_buffer_min_size"; |
+ |
+// Options for PaceSender. |
+const char kOptionPacerMaxBurstSize[] = "pacer_max_burst_size"; |
+const char kOptionPacerTargetBurstSize[] = "pacer_target_burst_size"; |
+ |
+// Wifi options. |
+const char kOptionWifiDisableScan[] = "disable_wifi_scan"; |
+const char kOptionWifiMediaStreamingMode[] = "media_streaming_mode"; |
+ |
+class TransportClient : public media::cast::CastTransportSender::Client { |
+ public: |
+ TransportClient(int32_t channel_id, |
+ cast::CastTransportHostFilter* cast_transport_host_filter) |
+ : channel_id_(channel_id), |
+ cast_transport_host_filter_(cast_transport_host_filter) {} |
+ |
+ void OnStatusChanged(media::cast::CastTransportStatus status) final; |
+ void OnLoggingEventsReceived( |
+ scoped_ptr<std::vector<media::cast::FrameEvent>> frame_events, |
+ scoped_ptr<std::vector<media::cast::PacketEvent>> packet_events) final; |
+ void ProcessRtpPacket(scoped_ptr<media::cast::Packet> packet) final; |
+ |
+ private: |
+ const int32_t channel_id_; |
+ cast::CastTransportHostFilter* const cast_transport_host_filter_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TransportClient); |
+}; |
+ |
+void TransportClient::OnStatusChanged(media::cast::CastTransportStatus status) { |
+ cast_transport_host_filter_->Send( |
+ new CastMsg_NotifyStatusChange(channel_id_, status)); |
+} |
+ |
+void TransportClient::OnLoggingEventsReceived( |
+ scoped_ptr<std::vector<media::cast::FrameEvent>> frame_events, |
+ scoped_ptr<std::vector<media::cast::PacketEvent>> packet_events) { |
+ if (frame_events->empty() && packet_events->empty()) |
+ return; |
+ cast_transport_host_filter_->Send( |
+ new CastMsg_RawEvents(channel_id_, *packet_events, *frame_events)); |
} |
+void TransportClient::ProcessRtpPacket(scoped_ptr<media::cast::Packet> packet) { |
+ cast_transport_host_filter_->Send( |
+ new CastMsg_ReceivedPacket(channel_id_, *packet)); |
+} |
+ |
+int LookupOptionWithDefault(const base::DictionaryValue& options, |
+ const std::string& path, |
+ int default_value) { |
+ int ret; |
+ if (options.GetInteger(path, &ret)) { |
+ return ret; |
+ } else { |
+ return default_value; |
+ } |
+} |
+ |
+int32_t GetTransportSendBufferSize(const base::DictionaryValue& options) { |
+ // Socket send buffer size needs to be at least greater than one burst |
+ // size. |
+ int32_t max_burst_size = |
+ LookupOptionWithDefault(options, kOptionPacerMaxBurstSize, |
+ media::cast::kMaxBurstSize) * |
+ media::cast::kMaxIpPacketSize; |
+ int32_t min_send_buffer_size = |
+ LookupOptionWithDefault(options, kOptionSendBufferMinSize, 0); |
+ return std::max(max_burst_size, min_send_buffer_size); |
+} |
+ |
+} // namespace |
+ |
namespace cast { |
CastTransportHostFilter::CastTransportHostFilter() |
@@ -26,6 +104,12 @@ CastTransportHostFilter::CastTransportHostFilter() |
CastTransportHostFilter::~CastTransportHostFilter() {} |
+void CastTransportHostFilter::OnStatusChanged( |
+ int32_t channel_id, |
+ media::cast::CastTransportStatus status) { |
+ Send(new CastMsg_NotifyStatusChange(channel_id, status)); |
+} |
+ |
bool CastTransportHostFilter::OnMessageReceived(const IPC::Message& message) { |
bool handled = true; |
IPC_BEGIN_MESSAGE_MAP(CastTransportHostFilter, message) |
@@ -49,27 +133,6 @@ bool CastTransportHostFilter::OnMessageReceived(const IPC::Message& message) { |
return handled; |
} |
-void CastTransportHostFilter::ReceivedPacket( |
- int32_t channel_id, |
- scoped_ptr<media::cast::Packet> packet) { |
- Send(new CastMsg_ReceivedPacket(channel_id, *packet)); |
-} |
- |
-void CastTransportHostFilter::NotifyStatusChange( |
- int32_t channel_id, |
- media::cast::CastTransportStatus status) { |
- Send(new CastMsg_NotifyStatusChange(channel_id, status)); |
-} |
- |
-void CastTransportHostFilter::SendRawEvents( |
- int32_t channel_id, |
- scoped_ptr<std::vector<media::cast::FrameEvent>> frame_events, |
- scoped_ptr<std::vector<media::cast::PacketEvent>> packet_events) { |
- if (frame_events->empty() && packet_events->empty()) |
- return; |
- Send(new CastMsg_RawEvents(channel_id, *packet_events, *frame_events)); |
-} |
- |
void CastTransportHostFilter::SendRtt(int32_t channel_id, |
uint32_t ssrc, |
base::TimeDelta rtt) { |
@@ -100,24 +163,23 @@ void CastTransportHostFilter::OnNew(int32_t channel_id, |
id_map_.Remove(channel_id); |
} |
+ scoped_ptr<TransportClient> transport_client = |
+ make_scoped_ptr(new TransportClient(channel_id, this)); |
+ scoped_ptr<media::cast::UdpTransport> udp_transport( |
+ new media::cast::UdpTransport( |
+ g_browser_process->net_log(), base::ThreadTaskRunnerHandle::Get(), |
+ local_end_point, remote_end_point, |
+ GetTransportSendBufferSize(options), |
+ base::Bind(&CastTransportHostFilter::OnStatusChanged, |
+ weak_factory_.GetWeakPtr(), channel_id))); |
+ SetUdpOptions(udp_transport.get(), options); |
scoped_ptr<media::cast::CastTransportSender> sender = |
media::cast::CastTransportSender::Create( |
- g_browser_process->net_log(), |
- &clock_, |
- local_end_point, |
- remote_end_point, |
- make_scoped_ptr(options.DeepCopy()), |
- base::Bind(&CastTransportHostFilter::NotifyStatusChange, |
- weak_factory_.GetWeakPtr(), |
- channel_id), |
- base::Bind(&CastTransportHostFilter::SendRawEvents, |
- weak_factory_.GetWeakPtr(), |
- channel_id), |
- base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs), |
- base::Bind(&CastTransportHostFilter::ReceivedPacket, |
- weak_factory_.GetWeakPtr(), |
- channel_id), |
+ &clock_, base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs), |
+ std::move(transport_client), std::move(udp_transport), |
base::ThreadTaskRunnerHandle::Get()); |
+ SetPacedSenderOptions(sender.get(), options); |
+ SetWifiOptions(sender.get(), options); |
id_map_.AddWithID(sender.release(), channel_id); |
} |
@@ -264,5 +326,46 @@ void CastTransportHostFilter::OnSendRtcpFromRtpReceiver( |
} |
} |
+void CastTransportHostFilter::SetUdpOptions( |
+ media::cast::UdpTransport* transport, |
+ const base::DictionaryValue& options) { |
+ if (options.HasKey(kOptionDscp)) { |
+ // The default DSCP value for cast is AF41. Which gives it a higher |
+ // priority over other traffic. |
+ transport->SetDscp(net::DSCP_AF41); |
+ } |
+#if defined(OS_WIN) |
+ if (!options.HasKey(kOptionDisableNonBlockingIO)) { |
+ transport->UseNonBlockingIO(); |
+ } |
+#endif |
+} |
+ |
+void CastTransportHostFilter::SetPacedSenderOptions( |
+ media::cast::CastTransportSender* transport_sender, |
+ const base::DictionaryValue& options) { |
+ int burst_size = LookupOptionWithDefault(options, kOptionPacerTargetBurstSize, |
+ media::cast::kTargetBurstSize); |
+ if (burst_size != media::cast::kTargetBurstSize) |
+ transport_sender->GetPacedSender()->SetTargetBurstSize(burst_size); |
+ burst_size = LookupOptionWithDefault(options, kOptionPacerMaxBurstSize, |
+ media::cast::kMaxBurstSize); |
+ if (burst_size != media::cast::kMaxBurstSize) |
+ transport_sender->GetPacedSender()->SetMaxBurstSize(burst_size); |
+} |
+ |
+void CastTransportHostFilter::SetWifiOptions( |
+ media::cast::CastTransportSender* transport_sender, |
+ const base::DictionaryValue& options) { |
+ int wifi_options = 0; |
+ if (options.HasKey(kOptionWifiDisableScan)) { |
+ wifi_options |= net::WIFI_OPTIONS_DISABLE_SCAN; |
+ } |
+ if (options.HasKey(kOptionWifiMediaStreamingMode)) { |
+ wifi_options |= net::WIFI_OPTIONS_MEDIA_STREAMING_MODE; |
+ } |
+ if (wifi_options) |
+ transport_sender->SetWifiOptions(wifi_options); |
+} |
} // namespace cast |