| 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
|
|
|