summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxjz <xjz@chromium.org>2016-02-23 16:20:17 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-24 00:21:33 +0000
commit74f752173cf8084d9f96073eaa88236f0ac54b79 (patch)
tree2efcdd1178f748b40113e09505195cb5a8cca68b
parentbb910a25c0cdb25494d2b7c1ad62cdb0dc3fe018 (diff)
downloadchromium_src-74f752173cf8084d9f96073eaa88236f0ac54b79.zip
chromium_src-74f752173cf8084d9f96073eaa88236f0ac54b79.tar.gz
chromium_src-74f752173cf8084d9f96073eaa88236f0ac54b79.tar.bz2
Simplify interface for media/cast: CastTransportSenderImpl
Defined an interface to reduce the 11-arg constructor down to 4 args. BUG=557477 Review URL: https://codereview.chromium.org/1515023002 Cr-Commit-Position: refs/heads/master@{#377148}
-rw-r--r--chrome/browser/media/cast_transport_host_filter.cc94
-rw-r--r--chrome/browser/media/cast_transport_host_filter.h12
-rw-r--r--chrome/renderer/media/cast_transport_sender_ipc.h2
-rw-r--r--media/cast/net/cast_transport_config.h9
-rw-r--r--media/cast/net/cast_transport_sender.h40
-rw-r--r--media/cast/net/cast_transport_sender_impl.cc191
-rw-r--r--media/cast/net/cast_transport_sender_impl.h86
-rw-r--r--media/cast/net/cast_transport_sender_impl_unittest.cc175
-rw-r--r--media/cast/net/mock_cast_transport_sender.h1
-rw-r--r--media/cast/net/pacing/paced_sender.h7
-rw-r--r--media/cast/net/pacing/paced_sender_unittest.cc5
-rw-r--r--media/cast/net/rtp/rtp_packetizer_unittest.cc5
-rw-r--r--media/cast/net/udp_transport.cc65
-rw-r--r--media/cast/net/udp_transport.h25
-rw-r--r--media/cast/net/udp_transport_unittest.cc4
-rw-r--r--media/cast/sender/audio_sender_unittest.cc53
-rw-r--r--media/cast/sender/video_sender_unittest.cc96
-rw-r--r--media/cast/test/cast_benchmarks.cc143
-rw-r--r--media/cast/test/end2end_unittest.cc181
-rw-r--r--media/cast/test/loopback_transport.h5
-rw-r--r--media/cast/test/sender.cc39
-rw-r--r--media/cast/test/simulator.cc97
-rw-r--r--media/cast/test/utility/in_process_receiver.cc35
-rw-r--r--media/cast/test/utility/in_process_receiver.h18
24 files changed, 782 insertions, 606 deletions
diff --git a/chrome/browser/media/cast_transport_host_filter.cc b/chrome/browser/media/cast_transport_host_filter.cc
index ee31f41..acdcd05 100644
--- a/chrome/browser/media/cast_transport_host_filter.cc
+++ b/chrome/browser/media/cast_transport_host_filter.cc
@@ -16,8 +16,47 @@ namespace {
// How often to send raw events.
const int kSendRawEventsIntervalSecs = 1;
+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));
+}
+
+} // namespace
+
namespace cast {
CastTransportHostFilter::CastTransportHostFilter()
@@ -26,6 +65,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 +94,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 +124,19 @@ void CastTransportHostFilter::OnNew(int32_t channel_id,
id_map_.Remove(channel_id);
}
+ 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,
+ base::Bind(&CastTransportHostFilter::OnStatusChanged,
+ weak_factory_.GetWeakPtr(), channel_id)));
+ udp_transport->SetUdpOptions(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),
- base::ThreadTaskRunnerHandle::Get());
+ &clock_, base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs),
+ make_scoped_ptr(new TransportClient(channel_id, this)),
+ std::move(udp_transport), base::ThreadTaskRunnerHandle::Get());
+ sender->SetOptions(options);
id_map_.AddWithID(sender.release(), channel_id);
}
@@ -264,5 +283,4 @@ void CastTransportHostFilter::OnSendRtcpFromRtpReceiver(
}
}
-
} // namespace cast
diff --git a/chrome/browser/media/cast_transport_host_filter.h b/chrome/browser/media/cast_transport_host_filter.h
index 127e7d1..2331e97 100644
--- a/chrome/browser/media/cast_transport_host_filter.h
+++ b/chrome/browser/media/cast_transport_host_filter.h
@@ -16,6 +16,7 @@
#include "media/cast/cast_sender.h"
#include "media/cast/logging/logging_defines.h"
#include "media/cast/net/cast_transport_sender.h"
+#include "media/cast/net/udp_transport.h"
namespace content {
class PowerSaveBlocker;
@@ -30,18 +31,13 @@ class CastTransportHostFilter : public content::BrowserMessageFilter {
private:
~CastTransportHostFilter() override;
- void NotifyStatusChange(int32_t channel_id,
- media::cast::CastTransportStatus result);
- void SendRawEvents(
- int32_t channel_id,
- scoped_ptr<std::vector<media::cast::FrameEvent>> frame_events,
- scoped_ptr<std::vector<media::cast::PacketEvent>> packet_events);
+ // Status callback to create UdpTransport.
+ void OnStatusChanged(int32_t channel_id,
+ media::cast::CastTransportStatus status);
void SendRtt(int32_t channel_id, uint32_t ssrc, base::TimeDelta rtt);
void SendCastMessage(int32_t channel_id,
uint32_t ssrc,
const media::cast::RtcpCastMessage& cast_message);
- void ReceivedPacket(int32_t channel_id,
- scoped_ptr<media::cast::Packet> packet);
// BrowserMessageFilter implementation.
bool OnMessageReceived(const IPC::Message& message) override;
diff --git a/chrome/renderer/media/cast_transport_sender_ipc.h b/chrome/renderer/media/cast_transport_sender_ipc.h
index af66c03..2903d31 100644
--- a/chrome/renderer/media/cast_transport_sender_ipc.h
+++ b/chrome/renderer/media/cast_transport_sender_ipc.h
@@ -62,6 +62,8 @@ class CastTransportSenderIPC
const media::cast::RtpReceiverStatistics* rtp_receiver_statistics)
override;
+ void SetOptions(const base::DictionaryValue& options) final {}
+
void OnNotifyStatusChange(
media::cast::CastTransportStatus status);
void OnRawEvents(const std::vector<media::cast::PacketEvent>& packet_events,
diff --git a/media/cast/net/cast_transport_config.h b/media/cast/net/cast_transport_config.h
index 82823ad..dc63bee 100644
--- a/media/cast/net/cast_transport_config.h
+++ b/media/cast/net/cast_transport_config.h
@@ -126,6 +126,8 @@ typedef base::Callback<void(scoped_ptr<Packet> packet)> PacketReceiverCallback;
typedef base::Callback<bool(scoped_ptr<Packet> packet)>
PacketReceiverCallbackWithStatus;
+// TODO(xjz): Rename PacketSender as it also deals with receiving packets.
+// http://crbug.com/589157.
class PacketSender {
public:
// Send a packet to the network. Returns false if the network is blocked
@@ -138,6 +140,13 @@ class PacketSender {
// Returns the number of bytes ever sent.
virtual int64_t GetBytesSent() = 0;
+ // Start receiving packets. Pakets are submitted to |packet_receiver|.
+ virtual void StartReceiving(
+ const PacketReceiverCallbackWithStatus& packet_receiver) = 0;
+
+ // Stop receiving packets.
+ virtual void StopReceiving() = 0;
+
virtual ~PacketSender() {}
};
diff --git a/media/cast/net/cast_transport_sender.h b/media/cast/net/cast_transport_sender.h
index 0ff76e1..3272f74 100644
--- a/media/cast/net/cast_transport_sender.h
+++ b/media/cast/net/cast_transport_sender.h
@@ -25,6 +25,7 @@
#include "base/single_thread_task_runner.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/tick_clock.h"
+#include "base/values.h"
#include "media/cast/logging/logging_defines.h"
#include "media/cast/net/cast_transport_config.h"
#include "media/cast/net/cast_transport_defines.h"
@@ -42,6 +43,7 @@ class NetLog;
namespace media {
namespace cast {
+
struct RtpReceiverStatistics;
struct RtcpTimeData;
@@ -54,19 +56,36 @@ typedef base::Callback<void(scoped_ptr<std::vector<FrameEvent>>,
scoped_ptr<std::vector<PacketEvent>>)>
BulkRawEventsCallback;
+// TODO(xjz): Rename CastTransportSender as it also deals with receiving
+// packets. http://crbug.com/589157.
// The application should only trigger this class from the transport thread.
class CastTransportSender : public base::NonThreadSafe {
public:
+ // Interface used for receiving status updates, raw events, and RTP packets
+ // from CastTransportSender.
+ class Client {
+ public:
+ virtual ~Client(){};
+
+ // Audio and Video transport status change is reported on this callback.
+ virtual void OnStatusChanged(CastTransportStatus status) = 0;
+
+ // Raw events will be invoked on this callback periodically, according to
+ // the configured logging flush interval passed to
+ // CastTransportSender::Create().
+ virtual void OnLoggingEventsReceived(
+ scoped_ptr<std::vector<FrameEvent>> frame_events,
+ scoped_ptr<std::vector<PacketEvent>> packet_events) = 0;
+
+ // Called to pass RTP packets to the Client.
+ virtual void ProcessRtpPacket(scoped_ptr<Packet> packet) = 0;
+ };
+
static scoped_ptr<CastTransportSender> Create(
- net::NetLog* net_log,
- base::TickClock* clock,
- const net::IPEndPoint& local_end_point,
- const net::IPEndPoint& remote_end_point,
- scoped_ptr<base::DictionaryValue> options,
- const CastTransportStatusCallback& status_callback,
- const BulkRawEventsCallback& raw_events_callback,
- base::TimeDelta raw_events_callback_interval,
- const PacketReceiverCallback& packet_callback,
+ base::TickClock* clock, // Owned by the caller.
+ base::TimeDelta logging_flush_interval,
+ scoped_ptr<Client> client,
+ scoped_ptr<PacketSender> transport,
const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner);
virtual ~CastTransportSender() {}
@@ -122,6 +141,9 @@ class CastTransportSender : public base::NonThreadSafe {
base::TimeDelta target_delay,
const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events,
const RtpReceiverStatistics* rtp_receiver_statistics) = 0;
+
+ // Set options for the PacedSender and Wifi.
+ virtual void SetOptions(const base::DictionaryValue& options) = 0;
};
} // namespace cast
diff --git a/media/cast/net/cast_transport_sender_impl.cc b/media/cast/net/cast_transport_sender_impl.cc
index c1b700df..2962967 100644
--- a/media/cast/net/cast_transport_sender_impl.cc
+++ b/media/cast/net/cast_transport_sender_impl.cc
@@ -10,28 +10,22 @@
#include <utility>
#include "base/single_thread_task_runner.h"
-#include "base/values.h"
#include "build/build_config.h"
#include "media/cast/net/cast_transport_defines.h"
#include "media/cast/net/rtcp/receiver_rtcp_session.h"
#include "media/cast/net/rtcp/sender_rtcp_session.h"
-#include "media/cast/net/udp_transport.h"
#include "net/base/net_errors.h"
-#include "net/base/network_interfaces.h"
namespace media {
namespace cast {
namespace {
-// See header file for what these mean.
-const char kOptionDscp[] = "DSCP";
-#if defined(OS_WIN)
-const char kOptionDisableNonBlockingIO[] = "disable_non_blocking_io";
-#endif
-const char kOptionPacerTargetBurstSize[] = "pacer_target_burst_size";
+// Options for PaceSender.
const char kOptionPacerMaxBurstSize[] = "pacer_max_burst_size";
-const char kOptionSendBufferMinSize[] = "send_buffer_min_size";
+const char kOptionPacerTargetBurstSize[] = "pacer_target_burst_size";
+
+// Wifi options.
const char kOptionWifiDisableScan[] = "disable_wifi_scan";
const char kOptionWifiMediaStreamingMode[] = "media_streaming_mode";
@@ -46,35 +40,17 @@ int LookupOptionWithDefault(const base::DictionaryValue& options,
}
}
-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,
- kMaxBurstSize) *
- kMaxIpPacketSize;
- int32_t min_send_buffer_size =
- LookupOptionWithDefault(options, kOptionSendBufferMinSize, 0);
- return std::max(max_burst_size, min_send_buffer_size);
-}
-
} // namespace
scoped_ptr<CastTransportSender> CastTransportSender::Create(
- net::NetLog* net_log,
- base::TickClock* clock,
- const net::IPEndPoint& local_end_point,
- const net::IPEndPoint& remote_end_point,
- scoped_ptr<base::DictionaryValue> options,
- const CastTransportStatusCallback& status_callback,
- const BulkRawEventsCallback& raw_events_callback,
- base::TimeDelta raw_events_callback_interval,
- const PacketReceiverCallback& packet_callback,
+ base::TickClock* clock, // Owned by the caller.
+ base::TimeDelta logging_flush_interval,
+ scoped_ptr<Client> client,
+ scoped_ptr<PacketSender> transport,
const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) {
return scoped_ptr<CastTransportSender>(new CastTransportSenderImpl(
- net_log, clock, local_end_point, remote_end_point, std::move(options),
- status_callback, raw_events_callback, raw_events_callback_interval,
- transport_task_runner.get(), packet_callback, NULL));
+ clock, logging_flush_interval, std::move(client), std::move(transport),
+ transport_task_runner.get()));
}
PacketReceiverCallback CastTransportSender::PacketReceiverForTesting() {
@@ -82,83 +58,41 @@ PacketReceiverCallback CastTransportSender::PacketReceiverForTesting() {
}
CastTransportSenderImpl::CastTransportSenderImpl(
- net::NetLog* net_log,
base::TickClock* clock,
- const net::IPEndPoint& local_end_point,
- const net::IPEndPoint& remote_end_point,
- scoped_ptr<base::DictionaryValue> options,
- const CastTransportStatusCallback& status_callback,
- const BulkRawEventsCallback& raw_events_callback,
- base::TimeDelta raw_events_callback_interval,
- const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
- const PacketReceiverCallback& packet_callback,
- PacketSender* external_transport)
+ base::TimeDelta logging_flush_interval,
+ scoped_ptr<Client> client,
+ scoped_ptr<PacketSender> transport,
+ const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner)
: clock_(clock),
- status_callback_(status_callback),
+ logging_flush_interval_(logging_flush_interval),
+ transport_client_(std::move(client)),
+ transport_(std::move(transport)),
transport_task_runner_(transport_task_runner),
- transport_(external_transport
- ? nullptr
- : new UdpTransport(net_log,
- transport_task_runner,
- local_end_point,
- remote_end_point,
- GetTransportSendBufferSize(*options),
- status_callback)),
- pacer_(LookupOptionWithDefault(*options,
- kOptionPacerTargetBurstSize,
- kTargetBurstSize),
- LookupOptionWithDefault(*options,
- kOptionPacerMaxBurstSize,
- kMaxBurstSize),
+ pacer_(kTargetBurstSize,
+ kMaxBurstSize,
clock,
- raw_events_callback.is_null() ? nullptr : &recent_packet_events_,
- external_transport ? external_transport : transport_.get(),
+ logging_flush_interval > base::TimeDelta() ? &recent_packet_events_
+ : nullptr,
+ transport_.get(),
transport_task_runner),
- raw_events_callback_(raw_events_callback),
- raw_events_callback_interval_(raw_events_callback_interval),
last_byte_acked_for_audio_(0),
- packet_callback_(packet_callback),
weak_factory_(this) {
- DCHECK(clock_);
- if (!raw_events_callback_.is_null()) {
- DCHECK(raw_events_callback_interval > base::TimeDelta());
- transport_task_runner->PostDelayedTask(
- FROM_HERE,
- base::Bind(&CastTransportSenderImpl::SendRawEvents,
- weak_factory_.GetWeakPtr()),
- raw_events_callback_interval);
- }
- if (transport_) {
- 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
- transport_->StartReceiving(
- base::Bind(&CastTransportSenderImpl::OnReceivedPacket,
- base::Unretained(this)));
- 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) {
- wifi_options_autoreset_ = net::SetWifiOptions(wifi_options);
- }
+ DCHECK(clock);
+ DCHECK(transport_client_);
+ DCHECK(transport_);
+ DCHECK(transport_task_runner_);
+ if (logging_flush_interval_ > base::TimeDelta()) {
+ transport_task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&CastTransportSenderImpl::SendRawEvents,
+ weak_factory_.GetWeakPtr()),
+ logging_flush_interval_);
}
+ transport_->StartReceiving(base::Bind(
+ &CastTransportSenderImpl::OnReceivedPacket, base::Unretained(this)));
}
CastTransportSenderImpl::~CastTransportSenderImpl() {
- if (transport_) {
- transport_->StopReceiving();
- }
+ transport_->StopReceiving();
}
void CastTransportSenderImpl::InitializeAudio(
@@ -168,7 +102,7 @@ void CastTransportSenderImpl::InitializeAudio(
LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty())
<< "Unsafe to send audio with encryption DISABLED.";
if (!audio_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) {
- status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED);
+ transport_client_->OnStatusChanged(TRANSPORT_AUDIO_UNINITIALIZED);
return;
}
@@ -177,10 +111,10 @@ void CastTransportSenderImpl::InitializeAudio(
// Audio packets have a higher priority.
pacer_.RegisterAudioSsrc(config.ssrc);
pacer_.RegisterPrioritySsrc(config.ssrc);
- status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED);
+ transport_client_->OnStatusChanged(TRANSPORT_AUDIO_INITIALIZED);
} else {
audio_sender_.reset();
- status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED);
+ transport_client_->OnStatusChanged(TRANSPORT_AUDIO_UNINITIALIZED);
return;
}
@@ -192,7 +126,7 @@ void CastTransportSenderImpl::InitializeAudio(
clock_, &pacer_, config.ssrc, config.feedback_ssrc));
pacer_.RegisterAudioSsrc(config.ssrc);
AddValidSsrc(config.feedback_ssrc);
- status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED);
+ transport_client_->OnStatusChanged(TRANSPORT_AUDIO_INITIALIZED);
}
void CastTransportSenderImpl::InitializeVideo(
@@ -202,14 +136,14 @@ void CastTransportSenderImpl::InitializeVideo(
LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty())
<< "Unsafe to send video with encryption DISABLED.";
if (!video_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) {
- status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED);
+ transport_client_->OnStatusChanged(TRANSPORT_VIDEO_UNINITIALIZED);
return;
}
video_sender_.reset(new RtpSender(transport_task_runner_, &pacer_));
if (!video_sender_->Initialize(config)) {
video_sender_.reset();
- status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED);
+ transport_client_->OnStatusChanged(TRANSPORT_VIDEO_UNINITIALIZED);
return;
}
@@ -221,7 +155,7 @@ void CastTransportSenderImpl::InitializeVideo(
clock_, &pacer_, config.ssrc, config.feedback_ssrc));
pacer_.RegisterVideoSsrc(config.ssrc);
AddValidSsrc(config.feedback_ssrc);
- status_callback_.Run(TRANSPORT_VIDEO_INITIALIZED);
+ transport_client_->OnStatusChanged(TRANSPORT_VIDEO_INITIALIZED);
}
namespace {
@@ -327,7 +261,7 @@ PacketReceiverCallback CastTransportSenderImpl::PacketReceiverForTesting() {
}
void CastTransportSenderImpl::SendRawEvents() {
- DCHECK(!raw_events_callback_.is_null());
+ DCHECK(logging_flush_interval_ > base::TimeDelta());
if (!recent_frame_events_.empty() || !recent_packet_events_.empty()) {
scoped_ptr<std::vector<FrameEvent>> frame_events(
@@ -336,14 +270,14 @@ void CastTransportSenderImpl::SendRawEvents() {
scoped_ptr<std::vector<PacketEvent>> packet_events(
new std::vector<PacketEvent>());
packet_events->swap(recent_packet_events_);
- raw_events_callback_.Run(std::move(frame_events), std::move(packet_events));
+ transport_client_->OnLoggingEventsReceived(std::move(frame_events),
+ std::move(packet_events));
}
transport_task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&CastTransportSenderImpl::SendRawEvents,
- weak_factory_.GetWeakPtr()),
- raw_events_callback_interval_);
+ FROM_HERE, base::Bind(&CastTransportSenderImpl::SendRawEvents,
+ weak_factory_.GetWeakPtr()),
+ logging_flush_interval_);
}
bool CastTransportSenderImpl::OnReceivedPacket(scoped_ptr<Packet> packet) {
@@ -369,18 +303,14 @@ bool CastTransportSenderImpl::OnReceivedPacket(scoped_ptr<Packet> packet) {
video_rtcp_session_->IncomingRtcpPacket(data, length)) {
return true;
}
- if (packet_callback_.is_null()) {
- VLOG(1) << "Stale packet received.";
- return false;
- }
- packet_callback_.Run(std::move(packet));
+ transport_client_->ProcessRtpPacket(std::move(packet));
return true;
}
void CastTransportSenderImpl::OnReceivedLogMessage(
EventMediaType media_type,
const RtcpReceiverLogMessage& log) {
- if (raw_events_callback_.is_null())
+ if (logging_flush_interval_ <= base::TimeDelta())
return;
// Add received log messages into our log system.
@@ -460,6 +390,29 @@ void CastTransportSenderImpl::AddValidSsrc(uint32_t ssrc) {
valid_ssrcs_.insert(ssrc);
}
+void CastTransportSenderImpl::SetOptions(const base::DictionaryValue& options) {
+ // Set PacedSender options.
+ int burst_size = LookupOptionWithDefault(options, kOptionPacerTargetBurstSize,
+ media::cast::kTargetBurstSize);
+ if (burst_size != media::cast::kTargetBurstSize)
+ pacer_.SetTargetBurstSize(burst_size);
+ burst_size = LookupOptionWithDefault(options, kOptionPacerMaxBurstSize,
+ media::cast::kMaxBurstSize);
+ if (burst_size != media::cast::kMaxBurstSize)
+ pacer_.SetMaxBurstSize(burst_size);
+
+ // Set Wifi 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)
+ wifi_options_autoreset_ = net::SetWifiOptions(wifi_options);
+}
+
// TODO(isheriff): This interface needs clean up.
// https://crbug.com/569259
void CastTransportSenderImpl::SendRtcpFromRtpReceiver(
diff --git a/media/cast/net/cast_transport_sender_impl.h b/media/cast/net/cast_transport_sender_impl.h
index 53f8694..18b2db1 100644
--- a/media/cast/net/cast_transport_sender_impl.h
+++ b/media/cast/net/cast_transport_sender_impl.h
@@ -54,44 +54,12 @@ class UdpTransport;
class CastTransportSenderImpl : public CastTransportSender {
public:
- // |external_transport| is only used for testing.
- // |raw_events_callback|: Raw events will be returned on this callback
- // which will be invoked every |raw_events_callback_interval|.
- // This can be a null callback, i.e. if user is not interested in raw events.
- // |raw_events_callback_interval|: This can be |base::TimeDelta()| if
- // |raw_events_callback| is a null callback.
- // |options| contains optional settings for the transport, possible
- // keys are:
- // "DSCP" (value ignored)
- // - Turns DSCP on (higher IP Precedence and Type of Service).
- // "disable_non_blocking_io" (value ignored)
- // - Windows only. Turns off non-blocking IO for the socket.
- // Note: Non-blocking IO is, by default, enabled on all platforms.
- // "pacer_target_burst_size": int
- // - Specifies how many packets to send per 10 ms ideally.
- // "pacer_max_burst_size": int
- // - Specifies how many pakcets to send per 10 ms, maximum.
- // "send_buffer_min_size": int
- // - Specifies the minimum socket send buffer size.
- // "disable_wifi_scan" (value ignored)
- // - Disable wifi scans while streaming.
- // "media_streaming_mode" (value ignored)
- // - Turn media streaming mode on.
- // Note, these options may be ignored on some platforms.
- // TODO(hubbe): Too many callbacks, replace with an interface.
- // http://crbug.com/557477
CastTransportSenderImpl(
- net::NetLog* net_log,
- base::TickClock* clock,
- const net::IPEndPoint& local_end_point,
- const net::IPEndPoint& remote_end_point,
- scoped_ptr<base::DictionaryValue> options,
- const CastTransportStatusCallback& status_callback,
- const BulkRawEventsCallback& raw_events_callback,
- base::TimeDelta raw_events_callback_interval,
- const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
- const PacketReceiverCallback& packet_callback,
- PacketSender* external_transport);
+ base::TickClock* clock, // Owned by the caller.
+ base::TimeDelta logging_flush_interval,
+ scoped_ptr<Client> client,
+ scoped_ptr<PacketSender> transport,
+ const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner);
~CastTransportSenderImpl() final;
@@ -115,6 +83,20 @@ class CastTransportSenderImpl : public CastTransportSender {
PacketReceiverCallback PacketReceiverForTesting() final;
+ // Possible keys of |options| handled here are:
+ // "pacer_target_burst_size": int
+ // - Specifies how many packets to send per 10 ms ideally.
+ // "pacer_max_burst_size": int
+ // - Specifies how many pakcets to send per 10 ms, maximum.
+ // "send_buffer_min_size": int
+ // - Specifies the minimum socket send buffer size.
+ // "disable_wifi_scan" (value ignored)
+ // - Disable wifi scans while streaming.
+ // "media_streaming_mode" (value ignored)
+ // - Turn media streaming mode on.
+ // Note, these options may be ignored on some platforms.
+ void SetOptions(const base::DictionaryValue& options) final;
+
// CastTransportReceiver implementation.
void AddValidSsrc(uint32_t ssrc) final;
@@ -143,8 +125,8 @@ class CastTransportSenderImpl : public CastTransportSender {
bool cancel_rtx_if_not_in_list,
const DedupInfo& dedup_info);
- // If |raw_events_callback_| is non-null, calls it with events collected
- // in |recent_frame_events_| and |recent_packet_events_| since last call.
+ // If |logging_flush_interval| is set, this is called at approximate periodic
+ // intervals.
void SendRawEvents();
// Called when a packet is received.
@@ -159,18 +141,18 @@ class CastTransportSenderImpl : public CastTransportSender {
const RtcpCastMessageCallback& cast_message_cb,
const RtcpCastMessage& cast_message);
- base::TickClock* clock_; // Not owned by this class.
- CastTransportStatusCallback status_callback_;
- scoped_refptr<base::SingleThreadTaskRunner> transport_task_runner_;
+ base::TickClock* const clock_; // Not owned by this class.
+ const base::TimeDelta logging_flush_interval_;
+ const scoped_ptr<Client> transport_client_;
+ const scoped_ptr<PacketSender> transport_;
+ const scoped_refptr<base::SingleThreadTaskRunner> transport_task_runner_;
- // FrameEvents and PacketEvents pending delivery via |raw_events_callback_|.
- // Do not add elements to these when |raw_events_callback_.is_null()|.
+ // FrameEvents and PacketEvents pending delivery via raw events callback.
+ // Do not add elements to these when |logging_flush_interval| is
+ // |base::TimeDelta()|.
std::vector<FrameEvent> recent_frame_events_;
std::vector<PacketEvent> recent_packet_events_;
- // Interface to a UDP socket.
- scoped_ptr<UdpTransport> transport_;
-
// Packet sender that performs pacing.
PacedSender pacer_;
@@ -189,9 +171,6 @@ class CastTransportSenderImpl : public CastTransportSender {
TransportEncryptionHandler audio_encryptor_;
TransportEncryptionHandler video_encryptor_;
- BulkRawEventsCallback raw_events_callback_;
- base::TimeDelta raw_events_callback_interval_;
-
// Right after a frame is sent we record the number of bytes sent to the
// socket. We record the corresponding bytes sent for the most recent ACKed
// audio packet.
@@ -200,10 +179,9 @@ class CastTransportSenderImpl : public CastTransportSender {
// Packets that don't match these ssrcs are ignored.
std::set<uint32_t> valid_ssrcs_;
- // Called with incoming packets. (Unless they match the
- // channels created by Initialize{Audio,Video}.
- PacketReceiverCallback packet_callback_;
-
+ // While non-null, global WiFi behavior modifications are in effect. This is
+ // used, for example, to turn off WiFi scanning that tends to interfere with
+ // the reliability of UDP packet transmission.
scoped_ptr<net::ScopedWifiOptions> wifi_options_autoreset_;
base::WeakPtrFactory<CastTransportSenderImpl> weak_factory_;
diff --git a/media/cast/net/cast_transport_sender_impl_unittest.cc b/media/cast/net/cast_transport_sender_impl_unittest.cc
index db6c5df..f2e9d5c 100644
--- a/media/cast/net/cast_transport_sender_impl_unittest.cc
+++ b/media/cast/net/cast_transport_sender_impl_unittest.cc
@@ -23,9 +23,11 @@ namespace media {
namespace cast {
namespace {
+
const int64_t kStartMillisecond = INT64_C(12345678900000);
const uint32_t kVideoSsrc = 1;
const uint32_t kAudioSsrc = 2;
+
} // namespace
class FakePacketSender : public PacketSender {
@@ -46,6 +48,11 @@ class FakePacketSender : public PacketSender {
int64_t GetBytesSent() final { return bytes_sent_; }
+ void StartReceiving(
+ const PacketReceiverCallbackWithStatus& packet_receiver) final {}
+
+ void StopReceiving() final {}
+
void SetPaused(bool paused) {
paused_ = paused;
if (!paused && stored_packet_.get()) {
@@ -67,6 +74,9 @@ class FakePacketSender : public PacketSender {
};
class CastTransportSenderImplTest : public ::testing::Test {
+ public:
+ void ReceivedLoggingEvents() { num_times_logging_callback_called_++; }
+
protected:
CastTransportSenderImplTest() : num_times_logging_callback_called_(0) {
testing_clock_.Advance(
@@ -76,62 +86,16 @@ class CastTransportSenderImplTest : public ::testing::Test {
~CastTransportSenderImplTest() override {}
- void InitWithoutLogging() {
- transport_sender_.reset(
- new CastTransportSenderImpl(NULL,
- &testing_clock_,
- net::IPEndPoint(),
- net::IPEndPoint(),
- make_scoped_ptr(new base::DictionaryValue),
- base::Bind(&UpdateCastTransportStatus),
- BulkRawEventsCallback(),
- base::TimeDelta(),
- task_runner_,
- PacketReceiverCallback(),
- &transport_));
- task_runner_->RunTasks();
- }
-
- void InitWithOptions() {
- scoped_ptr<base::DictionaryValue> options(
- new base::DictionaryValue);
- options->SetBoolean("DHCP", true);
- options->SetBoolean("disable_wifi_scan", true);
- options->SetBoolean("media_streaming_mode", true);
- options->SetInteger("pacer_target_burst_size", 20);
- options->SetInteger("pacer_max_burst_size", 100);
- transport_sender_.reset(new CastTransportSenderImpl(
- NULL, &testing_clock_, net::IPEndPoint(), net::IPEndPoint(),
- std::move(options), base::Bind(&UpdateCastTransportStatus),
- BulkRawEventsCallback(), base::TimeDelta(), task_runner_,
- PacketReceiverCallback(), &transport_));
- task_runner_->RunTasks();
- }
-
- void InitWithLogging() {
- transport_sender_.reset(new CastTransportSenderImpl(
- NULL,
- &testing_clock_,
- net::IPEndPoint(),
- net::IPEndPoint(),
- make_scoped_ptr(new base::DictionaryValue),
- base::Bind(&UpdateCastTransportStatus),
- base::Bind(&CastTransportSenderImplTest::LogRawEvents,
- base::Unretained(this)),
- base::TimeDelta::FromMilliseconds(10),
- task_runner_,
- PacketReceiverCallback(),
- &transport_));
- task_runner_->RunTasks();
- }
+ void InitWithoutLogging();
+ void InitWithOptions();
+ void InitWithLogging();
void InitializeVideo() {
CastTransportRtpConfig rtp_config;
rtp_config.ssrc = kVideoSsrc;
rtp_config.feedback_ssrc = 2;
rtp_config.rtp_payload_type = 3;
- transport_sender_->InitializeVideo(rtp_config,
- RtcpCastMessageCallback(),
+ transport_sender_->InitializeVideo(rtp_config, RtcpCastMessageCallback(),
RtcpRttCallback());
}
@@ -140,26 +104,75 @@ class CastTransportSenderImplTest : public ::testing::Test {
rtp_config.ssrc = kAudioSsrc;
rtp_config.feedback_ssrc = 3;
rtp_config.rtp_payload_type = 4;
- transport_sender_->InitializeAudio(rtp_config,
- RtcpCastMessageCallback(),
+ transport_sender_->InitializeAudio(rtp_config, RtcpCastMessageCallback(),
RtcpRttCallback());
}
- void LogRawEvents(scoped_ptr<std::vector<FrameEvent>> frame_events,
- scoped_ptr<std::vector<PacketEvent>> packet_events) {
- num_times_logging_callback_called_++;
- }
-
- static void UpdateCastTransportStatus(CastTransportStatus status) {
- }
-
base::SimpleTestTickClock testing_clock_;
scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
scoped_ptr<CastTransportSenderImpl> transport_sender_;
- FakePacketSender transport_;
+ FakePacketSender* transport_; // Owned by CastTransportSender.
int num_times_logging_callback_called_;
};
+namespace {
+
+class TransportClient : public CastTransportSender::Client {
+ public:
+ explicit TransportClient(
+ CastTransportSenderImplTest* cast_transport_sender_impl_test)
+ : cast_transport_sender_impl_test_(cast_transport_sender_impl_test) {}
+
+ void OnStatusChanged(CastTransportStatus status) final{};
+ void OnLoggingEventsReceived(
+ scoped_ptr<std::vector<FrameEvent>> frame_events,
+ scoped_ptr<std::vector<PacketEvent>> packet_events) final {
+ CHECK(cast_transport_sender_impl_test_);
+ cast_transport_sender_impl_test_->ReceivedLoggingEvents();
+ };
+ void ProcessRtpPacket(scoped_ptr<Packet> packet) final{};
+
+ private:
+ CastTransportSenderImplTest* const cast_transport_sender_impl_test_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransportClient);
+};
+
+} // namespace
+
+void CastTransportSenderImplTest::InitWithoutLogging() {
+ transport_ = new FakePacketSender();
+ transport_sender_.reset(
+ new CastTransportSenderImpl(&testing_clock_, base::TimeDelta(),
+ make_scoped_ptr(new TransportClient(nullptr)),
+ make_scoped_ptr(transport_), task_runner_));
+ task_runner_->RunTasks();
+}
+
+void CastTransportSenderImplTest::InitWithOptions() {
+ scoped_ptr<base::DictionaryValue> options(new base::DictionaryValue);
+ options->SetBoolean("disable_wifi_scan", true);
+ options->SetBoolean("media_streaming_mode", true);
+ options->SetInteger("pacer_target_burst_size", 20);
+ options->SetInteger("pacer_max_burst_size", 100);
+ transport_ = new FakePacketSender();
+ transport_sender_.reset(
+ new CastTransportSenderImpl(&testing_clock_, base::TimeDelta(),
+ make_scoped_ptr(new TransportClient(nullptr)),
+ make_scoped_ptr(transport_), task_runner_));
+ transport_sender_->SetOptions(*options);
+ task_runner_->RunTasks();
+}
+
+void CastTransportSenderImplTest::InitWithLogging() {
+ transport_ = new FakePacketSender();
+ transport_sender_.reset(new CastTransportSenderImpl(
+ &testing_clock_, base::TimeDelta::FromMilliseconds(10),
+ make_scoped_ptr(new TransportClient(this)), make_scoped_ptr(transport_),
+ task_runner_));
+ task_runner_->RunTasks();
+}
+
TEST_F(CastTransportSenderImplTest, InitWithoutLogging) {
InitWithoutLogging();
task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));
@@ -187,7 +200,7 @@ TEST_F(CastTransportSenderImplTest, NacksCancelRetransmits) {
transport_sender_->InsertFrame(kVideoSsrc, fake_frame);
task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
- EXPECT_EQ(4, transport_.packets_sent());
+ EXPECT_EQ(4, transport_->packets_sent());
EXPECT_EQ(1, num_times_logging_callback_called_);
// Resend packet 0.
@@ -196,7 +209,7 @@ TEST_F(CastTransportSenderImplTest, NacksCancelRetransmits) {
missing_packets[1].insert(1);
missing_packets[1].insert(2);
- transport_.SetPaused(true);
+ transport_->SetPaused(true);
DedupInfo dedup_info;
dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10);
transport_sender_->ResendPackets(
@@ -212,13 +225,13 @@ TEST_F(CastTransportSenderImplTest, NacksCancelRetransmits) {
transport_sender_->OnReceivedCastMessage(kVideoSsrc,
RtcpCastMessageCallback(),
cast_message);
- transport_.SetPaused(false);
+ transport_->SetPaused(false);
task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
EXPECT_EQ(3, num_times_logging_callback_called_);
// Resend one packet in the socket when unpaused.
// Resend one more packet from NACK.
- EXPECT_EQ(6, transport_.packets_sent());
+ EXPECT_EQ(6, transport_->packets_sent());
}
TEST_F(CastTransportSenderImplTest, CancelRetransmits) {
@@ -236,14 +249,14 @@ TEST_F(CastTransportSenderImplTest, CancelRetransmits) {
transport_sender_->InsertFrame(kVideoSsrc, fake_frame);
task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
- EXPECT_EQ(4, transport_.packets_sent());
+ EXPECT_EQ(4, transport_->packets_sent());
EXPECT_EQ(1, num_times_logging_callback_called_);
// Resend all packets for frame 1.
MissingFramesAndPacketsMap missing_packets;
missing_packets[1].insert(kRtcpCastAllPacketsLost);
- transport_.SetPaused(true);
+ transport_->SetPaused(true);
DedupInfo dedup_info;
dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10);
transport_sender_->ResendPackets(
@@ -256,12 +269,12 @@ TEST_F(CastTransportSenderImplTest, CancelRetransmits) {
cancel_sending_frames.push_back(1);
transport_sender_->CancelSendingFrames(kVideoSsrc,
cancel_sending_frames);
- transport_.SetPaused(false);
+ transport_->SetPaused(false);
task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
EXPECT_EQ(2, num_times_logging_callback_called_);
// Resend one packet in the socket when unpaused.
- EXPECT_EQ(5, transport_.packets_sent());
+ EXPECT_EQ(5, transport_->packets_sent());
}
TEST_F(CastTransportSenderImplTest, Kickstart) {
@@ -277,12 +290,12 @@ TEST_F(CastTransportSenderImplTest, Kickstart) {
fake_frame.dependency = EncodedFrame::KEY;
fake_frame.data.resize(5000, ' ');
- transport_.SetPaused(true);
+ transport_->SetPaused(true);
transport_sender_->InsertFrame(kVideoSsrc, fake_frame);
transport_sender_->ResendFrameForKickstart(kVideoSsrc, 1);
- transport_.SetPaused(false);
+ transport_->SetPaused(false);
task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
- EXPECT_EQ(4, transport_.packets_sent());
+ EXPECT_EQ(4, transport_->packets_sent());
EXPECT_EQ(1, num_times_logging_callback_called_);
// Resend 2 packets for frame 1.
@@ -290,19 +303,19 @@ TEST_F(CastTransportSenderImplTest, Kickstart) {
missing_packets[1].insert(0);
missing_packets[1].insert(1);
- transport_.SetPaused(true);
+ transport_->SetPaused(true);
DedupInfo dedup_info;
dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10);
transport_sender_->ResendPackets(
kVideoSsrc, missing_packets, true, dedup_info);
transport_sender_->ResendFrameForKickstart(kVideoSsrc, 1);
- transport_.SetPaused(false);
+ transport_->SetPaused(false);
task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
EXPECT_EQ(2, num_times_logging_callback_called_);
// Resend one packet in the socket when unpaused.
// Two more retransmission packets sent.
- EXPECT_EQ(7, transport_.packets_sent());
+ EXPECT_EQ(7, transport_->packets_sent());
}
TEST_F(CastTransportSenderImplTest, DedupRetransmissionWithAudio) {
@@ -324,7 +337,7 @@ TEST_F(CastTransportSenderImplTest, DedupRetransmissionWithAudio) {
fake_audio.reference_time = testing_clock_.NowTicks();
transport_sender_->InsertFrame(kAudioSsrc, fake_audio);
task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2));
- EXPECT_EQ(2, transport_.packets_sent());
+ EXPECT_EQ(2, transport_->packets_sent());
// Ack the first audio frame.
RtcpCastMessage cast_message;
@@ -334,7 +347,7 @@ TEST_F(CastTransportSenderImplTest, DedupRetransmissionWithAudio) {
RtcpCastMessageCallback(),
cast_message);
task_runner_->RunTasks();
- EXPECT_EQ(2, transport_.packets_sent());
+ EXPECT_EQ(2, transport_->packets_sent());
EXPECT_EQ(0, num_times_logging_callback_called_); // Only 4 ms since last.
// Send a fake video frame that will be decomposed into 4 packets.
@@ -344,7 +357,7 @@ TEST_F(CastTransportSenderImplTest, DedupRetransmissionWithAudio) {
fake_video.data.resize(5000, ' ');
transport_sender_->InsertFrame(kVideoSsrc, fake_video);
task_runner_->RunTasks();
- EXPECT_EQ(6, transport_.packets_sent());
+ EXPECT_EQ(6, transport_->packets_sent());
EXPECT_EQ(0, num_times_logging_callback_called_); // Only 4 ms since last.
// Retransmission is reject because audio is not acked yet.
@@ -356,7 +369,7 @@ TEST_F(CastTransportSenderImplTest, DedupRetransmissionWithAudio) {
RtcpCastMessageCallback(),
cast_message);
task_runner_->RunTasks();
- EXPECT_EQ(6, transport_.packets_sent());
+ EXPECT_EQ(6, transport_->packets_sent());
EXPECT_EQ(1, num_times_logging_callback_called_);
// Ack the second audio frame.
@@ -368,7 +381,7 @@ TEST_F(CastTransportSenderImplTest, DedupRetransmissionWithAudio) {
RtcpCastMessageCallback(),
cast_message);
task_runner_->RunTasks();
- EXPECT_EQ(6, transport_.packets_sent());
+ EXPECT_EQ(6, transport_->packets_sent());
EXPECT_EQ(1, num_times_logging_callback_called_); // Only 6 ms since last.
// Retransmission of video packet now accepted.
@@ -380,7 +393,7 @@ TEST_F(CastTransportSenderImplTest, DedupRetransmissionWithAudio) {
RtcpCastMessageCallback(),
cast_message);
task_runner_->RunTasks();
- EXPECT_EQ(7, transport_.packets_sent());
+ EXPECT_EQ(7, transport_->packets_sent());
EXPECT_EQ(1, num_times_logging_callback_called_); // Only 8 ms since last.
task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2));
diff --git a/media/cast/net/mock_cast_transport_sender.h b/media/cast/net/mock_cast_transport_sender.h
index 371b419..bf1dfc0 100644
--- a/media/cast/net/mock_cast_transport_sender.h
+++ b/media/cast/net/mock_cast_transport_sender.h
@@ -45,6 +45,7 @@ class MockCastTransportSender : public CastTransportSender {
base::TimeDelta target_delay,
const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events,
const RtpReceiverStatistics* rtp_receiver_statistics));
+ MOCK_METHOD1(SetOptions, void(const base::DictionaryValue& options));
};
} // namespace cast
diff --git a/media/cast/net/pacing/paced_sender.h b/media/cast/net/pacing/paced_sender.h
index 714fe9d..8d45cc4 100644
--- a/media/cast/net/pacing/paced_sender.h
+++ b/media/cast/net/pacing/paced_sender.h
@@ -131,6 +131,13 @@ class PacedSender : public PacedPacketSender,
bool SendRtcpPacket(uint32_t ssrc, PacketRef packet) final;
void CancelSendingPacket(const PacketKey& packet_key) final;
+ void SetTargetBurstSize(int burst_size) {
+ target_burst_size_ = current_max_burst_size_ = next_max_burst_size_ =
+ next_next_max_burst_size_ = burst_size;
+ }
+
+ void SetMaxBurstSize(int burst_size) { max_burst_size_ = burst_size; }
+
private:
// Actually sends the packets to the transport.
void SendStoredPackets();
diff --git a/media/cast/net/pacing/paced_sender_unittest.cc b/media/cast/net/pacing/paced_sender_unittest.cc
index fec5c5f..89c341f 100644
--- a/media/cast/net/pacing/paced_sender_unittest.cc
+++ b/media/cast/net/pacing/paced_sender_unittest.cc
@@ -47,6 +47,11 @@ class TestPacketSender : public PacketSender {
int64_t GetBytesSent() final { return bytes_sent_; }
+ void StartReceiving(
+ const PacketReceiverCallbackWithStatus& packet_receiver) final {}
+
+ void StopReceiving() final {}
+
void AddExpectedSize(int expected_packet_size, int repeat_count) {
for (int i = 0; i < repeat_count; ++i) {
expected_packet_size_.push_back(expected_packet_size);
diff --git a/media/cast/net/rtp/rtp_packetizer_unittest.cc b/media/cast/net/rtp/rtp_packetizer_unittest.cc
index 5c58125..76aa232 100644
--- a/media/cast/net/rtp/rtp_packetizer_unittest.cc
+++ b/media/cast/net/rtp/rtp_packetizer_unittest.cc
@@ -80,6 +80,11 @@ class TestRtpPacketTransport : public PacketSender {
int64_t GetBytesSent() final { return 0; }
+ void StartReceiving(
+ const PacketReceiverCallbackWithStatus& packet_receiver) final {}
+
+ void StopReceiving() final {}
+
size_t number_of_packets_received() const { return packets_sent_; }
void set_expected_number_of_packets(size_t expected_number_of_packets) {
diff --git a/media/cast/net/udp_transport.cc b/media/cast/net/udp_transport.cc
index 2560b45..bf126bc 100644
--- a/media/cast/net/udp_transport.cc
+++ b/media/cast/net/udp_transport.cc
@@ -21,7 +21,13 @@ namespace media {
namespace cast {
namespace {
-const int kMaxPacketSize = 1500;
+
+const char kOptionDscp[] = "DSCP";
+#if defined(OS_WIN)
+const char kOptionDisableNonBlockingIO[] = "disable_non_blocking_io";
+#endif
+const char kOptionSendBufferMinSize[] = "send_buffer_min_size";
+const char kOptionPacerMaxBurstSize[] = "pacer_max_burst_size";
bool IsEmpty(const net::IPEndPoint& addr) {
net::IPAddressNumber empty_addr(addr.address().size());
@@ -30,6 +36,29 @@ bool IsEmpty(const net::IPEndPoint& addr) {
!addr.port();
}
+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
UdpTransport::UdpTransport(
@@ -37,7 +66,6 @@ UdpTransport::UdpTransport(
const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_proxy,
const net::IPEndPoint& local_end_point,
const net::IPEndPoint& remote_end_point,
- int32_t send_buffer_size,
const CastTransportStatusCallback& status_callback)
: io_thread_proxy_(io_thread_proxy),
local_addr_(local_end_point),
@@ -50,7 +78,8 @@ UdpTransport::UdpTransport(
receive_pending_(false),
client_connected_(false),
next_dscp_value_(net::DSCP_NO_CHANGE),
- send_buffer_size_(send_buffer_size),
+ send_buffer_size_(media::cast::kMaxBurstSize *
+ media::cast::kMaxIpPacketSize),
status_callback_(status_callback),
bytes_sent_(0),
weak_factory_(this) {
@@ -145,15 +174,13 @@ void UdpTransport::ReceiveNextPacket(int length_or_status) {
// the future when a packet is ready.
while (true) {
if (length_or_status == net::ERR_IO_PENDING) {
- next_packet_.reset(new Packet(kMaxPacketSize));
+ next_packet_.reset(new Packet(media::cast::kMaxIpPacketSize));
recv_buf_ = new net::WrappedIOBuffer(
reinterpret_cast<char*>(&next_packet_->front()));
- length_or_status =
- udp_socket_->RecvFrom(recv_buf_.get(),
- kMaxPacketSize,
- &recv_addr_,
- base::Bind(&UdpTransport::ReceiveNextPacket,
- weak_factory_.GetWeakPtr()));
+ length_or_status = udp_socket_->RecvFrom(
+ recv_buf_.get(), media::cast::kMaxIpPacketSize, &recv_addr_,
+ base::Bind(&UdpTransport::ReceiveNextPacket,
+ weak_factory_.GetWeakPtr()));
if (length_or_status == net::ERR_IO_PENDING) {
receive_pending_ = true;
return;
@@ -275,5 +302,23 @@ void UdpTransport::OnSent(const scoped_refptr<net::IOBuffer>& buf,
}
}
+void UdpTransport::SetUdpOptions(const base::DictionaryValue& options) {
+ SetSendBufferSize(GetTransportSendBufferSize(options));
+ if (options.HasKey(kOptionDscp)) {
+ // The default DSCP value for cast is AF41. Which gives it a higher
+ // priority over other traffic.
+ SetDscp(net::DSCP_AF41);
+ }
+#if defined(OS_WIN)
+ if (!options.HasKey(kOptionDisableNonBlockingIO)) {
+ UseNonBlockingIO();
+ }
+#endif
+}
+
+void UdpTransport::SetSendBufferSize(int32_t send_buffer_size) {
+ send_buffer_size_ = send_buffer_size;
+}
+
} // namespace cast
} // namespace media
diff --git a/media/cast/net/udp_transport.h b/media/cast/net/udp_transport.h
index 6da6ae3..c098a58 100644
--- a/media/cast/net/udp_transport.h
+++ b/media/cast/net/udp_transport.h
@@ -11,10 +11,12 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/values.h"
#include "build/build_config.h"
#include "media/cast/cast_environment.h"
#include "media/cast/net/cast_transport_config.h"
#include "media/cast/net/cast_transport_sender.h"
+#include "media/cast/net/pacing/paced_sender.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/udp/diff_serv_code_point.h"
@@ -44,18 +46,35 @@ class UdpTransport : public PacketSender {
const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_proxy,
const net::IPEndPoint& local_end_point,
const net::IPEndPoint& remote_end_point,
- int32_t send_buffer_size,
const CastTransportStatusCallback& status_callback);
~UdpTransport() final;
// Start receiving packets. Packets are submitted to |packet_receiver|.
- void StartReceiving(const PacketReceiverCallbackWithStatus& packet_receiver);
- void StopReceiving();
+ void StartReceiving(
+ const PacketReceiverCallbackWithStatus& packet_receiver) final;
+ void StopReceiving() final;
// Set a new DSCP value to the socket. The value will be set right before
// the next send.
void SetDscp(net::DiffServCodePoint dscp);
+ // Set UdpTransport options.
+ // Possible keys are:
+ // "pacer_max_burst_size": int
+ // - Specifies how many pakcets to send per 10 ms, maximum.
+ // "send_buffer_min_size": int
+ // - Specifies the minimum socket send buffer size.
+ // "DSCP" (value ignored)
+ // - Turns DSCP on (higher IP Precedence and Type of Service).
+ // "disable_non_blocking_io" (value ignored)
+ // - Windows only. Turns off non-blocking IO for the socket.
+ // Note: Non-blocking IO is, by default, enabled on all platforms.
+ void SetUdpOptions(const base::DictionaryValue& options);
+
+ // This has to be called before |StartReceiving()| to change the
+ // |send_buffer_size_|. Calling |SetUdpOptions()| will automatically call it.
+ void SetSendBufferSize(int32_t send_buffer_size);
+
#if defined(OS_WIN)
// Switch to use non-blocking IO. Must be called before StartReceiving().
void UseNonBlockingIO();
diff --git a/media/cast/net/udp_transport_unittest.cc b/media/cast/net/udp_transport_unittest.cc
index 1e7729b..b73c683 100644
--- a/media/cast/net/udp_transport_unittest.cc
+++ b/media/cast/net/udp_transport_unittest.cc
@@ -66,14 +66,14 @@ TEST(UdpTransport, SendAndReceive) {
message_loop.task_runner(),
free_local_port1,
free_local_port2,
- 65536,
base::Bind(&UpdateCastTransportStatus));
+ send_transport.SetSendBufferSize(65536);
UdpTransport recv_transport(NULL,
message_loop.task_runner(),
free_local_port2,
net::IPEndPoint(empty_addr_number, 0),
- 65536,
base::Bind(&UpdateCastTransportStatus));
+ recv_transport.SetSendBufferSize(65536);
Packet packet;
packet.push_back('t');
diff --git a/media/cast/sender/audio_sender_unittest.cc b/media/cast/sender/audio_sender_unittest.cc
index af6b9c4..bfe2383 100644
--- a/media/cast/sender/audio_sender_unittest.cc
+++ b/media/cast/sender/audio_sender_unittest.cc
@@ -35,6 +35,21 @@ void SaveOperationalStatus(OperationalStatus* out_status,
*out_status = in_status;
}
+class TransportClient : public CastTransportSender::Client {
+ public:
+ TransportClient() {}
+
+ void OnStatusChanged(CastTransportStatus status) final {
+ EXPECT_EQ(TRANSPORT_AUDIO_INITIALIZED, status);
+ };
+ void OnLoggingEventsReceived(
+ scoped_ptr<std::vector<FrameEvent>> frame_events,
+ scoped_ptr<std::vector<PacketEvent>> packet_events) final{};
+ void ProcessRtpPacket(scoped_ptr<Packet> packet) final{};
+
+ DISALLOW_COPY_AND_ASSIGN(TransportClient);
+};
+
} // namespace
class TestPacketSender : public PacketSender {
@@ -58,6 +73,11 @@ class TestPacketSender : public PacketSender {
int64_t GetBytesSent() final { return 0; }
+ void StartReceiving(
+ const PacketReceiverCallbackWithStatus& packet_receiver) final {}
+
+ void StopReceiving() final {}
+
int number_of_rtp_packets() const { return number_of_rtp_packets_; }
int number_of_rtcp_packets() const { return number_of_rtcp_packets_; }
@@ -86,20 +106,11 @@ class AudioSenderTest : public ::testing::Test {
audio_config_.bitrate = kDefaultAudioEncoderBitrate;
audio_config_.rtp_payload_type = 127;
- net::IPEndPoint dummy_endpoint;
-
- transport_sender_.reset(new CastTransportSenderImpl(
- NULL,
- testing_clock_,
- net::IPEndPoint(),
- dummy_endpoint,
- make_scoped_ptr(new base::DictionaryValue),
- base::Bind(&UpdateCastTransportStatus),
- BulkRawEventsCallback(),
- base::TimeDelta(),
- task_runner_,
- PacketReceiverCallback(),
- &transport_));
+ transport_ = new TestPacketSender();
+ transport_sender_.reset(
+ new CastTransportSenderImpl(testing_clock_, base::TimeDelta(),
+ make_scoped_ptr(new TransportClient()),
+ make_scoped_ptr(transport_), task_runner_));
OperationalStatus operational_status = STATUS_UNINITIALIZED;
audio_sender_.reset(new AudioSender(
cast_environment_,
@@ -112,12 +123,8 @@ class AudioSenderTest : public ::testing::Test {
~AudioSenderTest() override {}
- static void UpdateCastTransportStatus(CastTransportStatus status) {
- EXPECT_EQ(TRANSPORT_AUDIO_INITIALIZED, status);
- }
-
base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment.
- TestPacketSender transport_;
+ TestPacketSender* transport_; // Owned by CastTransportSender.
scoped_ptr<CastTransportSenderImpl> transport_sender_;
scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
scoped_ptr<AudioSender> audio_sender_;
@@ -135,8 +142,8 @@ TEST_F(AudioSenderTest, Encode20ms) {
audio_sender_->InsertAudio(std::move(bus), testing_clock_->NowTicks());
task_runner_->RunTasks();
- EXPECT_LE(1, transport_.number_of_rtp_packets());
- EXPECT_LE(1, transport_.number_of_rtcp_packets());
+ EXPECT_LE(1, transport_->number_of_rtp_packets());
+ EXPECT_LE(1, transport_->number_of_rtcp_packets());
}
TEST_F(AudioSenderTest, RtcpTimer) {
@@ -155,8 +162,8 @@ TEST_F(AudioSenderTest, RtcpTimer) {
base::TimeDelta::FromMilliseconds(1 + kRtcpReportIntervalMs * 3 / 2);
testing_clock_->Advance(max_rtcp_timeout);
task_runner_->RunTasks();
- EXPECT_LE(1, transport_.number_of_rtp_packets());
- EXPECT_LE(1, transport_.number_of_rtcp_packets());
+ EXPECT_LE(1, transport_->number_of_rtp_packets());
+ EXPECT_LE(1, transport_->number_of_rtcp_packets());
}
} // namespace cast
diff --git a/media/cast/sender/video_sender_unittest.cc b/media/cast/sender/video_sender_unittest.cc
index 9c5d9c4..3d315ea 100644
--- a/media/cast/sender/video_sender_unittest.cc
+++ b/media/cast/sender/video_sender_unittest.cc
@@ -77,6 +77,11 @@ class TestPacketSender : public PacketSender {
int64_t GetBytesSent() final { return 0; }
+ void StartReceiving(
+ const PacketReceiverCallbackWithStatus& packet_receiver) final {}
+
+ void StopReceiving() final {}
+
int number_of_rtp_packets() const { return number_of_rtp_packets_; }
int number_of_rtcp_packets() const { return number_of_rtcp_packets_; }
@@ -121,6 +126,21 @@ class PeerVideoSender : public VideoSender {
using VideoSender::OnReceivedCastFeedback;
};
+class TransportClient : public CastTransportSender::Client {
+ public:
+ TransportClient() {}
+
+ void OnStatusChanged(CastTransportStatus status) final {
+ EXPECT_EQ(TRANSPORT_VIDEO_INITIALIZED, status);
+ };
+ void OnLoggingEventsReceived(
+ scoped_ptr<std::vector<FrameEvent>> frame_events,
+ scoped_ptr<std::vector<PacketEvent>> packet_events) final{};
+ void ProcessRtpPacket(scoped_ptr<Packet> packet) final{};
+
+ DISALLOW_COPY_AND_ASSIGN(TransportClient);
+};
+
} // namespace
class VideoSenderTest : public ::testing::Test {
@@ -138,19 +158,11 @@ class VideoSenderTest : public ::testing::Test {
testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
vea_factory_.SetAutoRespond(true);
last_pixel_value_ = kPixelValue;
- net::IPEndPoint dummy_endpoint;
- transport_sender_.reset(new CastTransportSenderImpl(
- NULL,
- testing_clock_,
- dummy_endpoint,
- dummy_endpoint,
- make_scoped_ptr(new base::DictionaryValue),
- base::Bind(&UpdateCastTransportStatus),
- BulkRawEventsCallback(),
- base::TimeDelta(),
- task_runner_,
- PacketReceiverCallback(),
- &transport_));
+ transport_ = new TestPacketSender();
+ transport_sender_.reset(
+ new CastTransportSenderImpl(testing_clock_, base::TimeDelta(),
+ make_scoped_ptr(new TransportClient()),
+ make_scoped_ptr(transport_), task_runner_));
}
~VideoSenderTest() override {}
@@ -160,10 +172,6 @@ class VideoSenderTest : public ::testing::Test {
task_runner_->RunTasks();
}
- static void UpdateCastTransportStatus(CastTransportStatus status) {
- EXPECT_EQ(TRANSPORT_VIDEO_INITIALIZED, status);
- }
-
// If |external| is true then external video encoder (VEA) is used.
// |expect_init_success| is true if initialization is expected to succeed.
void InitEncoder(bool external, bool expect_init_success) {
@@ -229,7 +237,7 @@ class VideoSenderTest : public ::testing::Test {
const scoped_refptr<CastEnvironment> cast_environment_;
OperationalStatus operational_status_;
FakeVideoEncodeAcceleratorFactory vea_factory_;
- TestPacketSender transport_;
+ TestPacketSender* transport_; // Owned by CastTransportSender.
scoped_ptr<CastTransportSenderImpl> transport_sender_;
scoped_ptr<PeerVideoSender> video_sender_;
int last_pixel_value_;
@@ -249,8 +257,8 @@ TEST_F(VideoSenderTest, BuiltInEncoder) {
video_sender_->InsertRawVideoFrame(video_frame, reference_time);
task_runner_->RunTasks();
- EXPECT_LE(1, transport_.number_of_rtp_packets());
- EXPECT_LE(1, transport_.number_of_rtcp_packets());
+ EXPECT_LE(1, transport_->number_of_rtp_packets());
+ EXPECT_LE(1, transport_->number_of_rtcp_packets());
}
TEST_F(VideoSenderTest, ExternalEncoder) {
@@ -324,15 +332,15 @@ TEST_F(VideoSenderTest, RtcpTimer) {
base::TimeDelta::FromMilliseconds(1 + kRtcpReportIntervalMs * 3 / 2);
RunTasks(max_rtcp_timeout.InMilliseconds());
- EXPECT_LE(1, transport_.number_of_rtp_packets());
- EXPECT_LE(1, transport_.number_of_rtcp_packets());
+ EXPECT_LE(1, transport_->number_of_rtp_packets());
+ EXPECT_LE(1, transport_->number_of_rtcp_packets());
// Build Cast msg and expect RTCP packet.
RtcpCastMessage cast_feedback(1);
cast_feedback.media_ssrc = 2;
cast_feedback.ack_frame_id = 0;
video_sender_->OnReceivedCastFeedback(cast_feedback);
RunTasks(max_rtcp_timeout.InMilliseconds());
- EXPECT_LE(1, transport_.number_of_rtcp_packets());
+ EXPECT_LE(1, transport_->number_of_rtcp_packets());
}
TEST_F(VideoSenderTest, ResendTimer) {
@@ -359,9 +367,8 @@ TEST_F(VideoSenderTest, ResendTimer) {
// Make sure that we do a re-send.
RunTasks(max_resend_timeout.InMilliseconds());
// Should have sent at least 3 packets.
- EXPECT_LE(
- 3,
- transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
+ EXPECT_LE(3, transport_->number_of_rtp_packets() +
+ transport_->number_of_rtcp_packets());
}
TEST_F(VideoSenderTest, LogAckReceivedEvent) {
@@ -414,7 +421,7 @@ TEST_F(VideoSenderTest, StopSendingInTheAbsenceOfAck) {
video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
RunTasks(33);
}
- const int number_of_packets_sent = transport_.number_of_rtp_packets();
+ const int number_of_packets_sent = transport_->number_of_rtp_packets();
// Send 3 more frames - they should not be encoded, as we have not received
// any acks.
@@ -426,24 +433,21 @@ TEST_F(VideoSenderTest, StopSendingInTheAbsenceOfAck) {
// We expect a frame to be retransmitted because of duplicated ACKs.
// Only one packet of the frame is re-transmitted.
- EXPECT_EQ(number_of_packets_sent + 1,
- transport_.number_of_rtp_packets());
+ EXPECT_EQ(number_of_packets_sent + 1, transport_->number_of_rtp_packets());
// Start acking and make sure we're back to steady-state.
RtcpCastMessage cast_feedback(1);
cast_feedback.media_ssrc = 2;
cast_feedback.ack_frame_id = 0;
video_sender_->OnReceivedCastFeedback(cast_feedback);
- EXPECT_LE(
- 4,
- transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
+ EXPECT_LE(4, transport_->number_of_rtp_packets() +
+ transport_->number_of_rtcp_packets());
// Empty the pipeline.
RunTasks(100);
// Should have sent at least 7 packets.
- EXPECT_LE(
- 7,
- transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
+ EXPECT_LE(7, transport_->number_of_rtp_packets() +
+ transport_->number_of_rtcp_packets());
}
TEST_F(VideoSenderTest, DuplicateAckRetransmit) {
@@ -463,7 +467,7 @@ TEST_F(VideoSenderTest, DuplicateAckRetransmit) {
video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
RunTasks(33);
}
- const int number_of_packets_sent = transport_.number_of_rtp_packets();
+ const int number_of_packets_sent = transport_->number_of_rtp_packets();
// Send duplicated ACKs and mix some invalid NACKs.
for (int i = 0; i < 10; ++i) {
@@ -476,7 +480,7 @@ TEST_F(VideoSenderTest, DuplicateAckRetransmit) {
video_sender_->OnReceivedCastFeedback(ack_feedback);
video_sender_->OnReceivedCastFeedback(nack_feedback);
}
- EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets());
+ EXPECT_EQ(number_of_packets_sent, transport_->number_of_rtp_packets());
// Re-transmit one packet because of duplicated ACKs.
for (int i = 0; i < 3; ++i) {
@@ -485,7 +489,7 @@ TEST_F(VideoSenderTest, DuplicateAckRetransmit) {
ack_feedback.ack_frame_id = 0;
video_sender_->OnReceivedCastFeedback(ack_feedback);
}
- EXPECT_EQ(number_of_packets_sent + 1, transport_.number_of_rtp_packets());
+ EXPECT_EQ(number_of_packets_sent + 1, transport_->number_of_rtp_packets());
}
TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) {
@@ -506,14 +510,14 @@ TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) {
RunTasks(33);
}
// Pause the transport
- transport_.SetPause(true);
+ transport_->SetPause(true);
// Insert one more video frame.
video_frame = GetLargeNewVideoFrame();
video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
RunTasks(33);
- const int number_of_packets_sent = transport_.number_of_rtp_packets();
+ const int number_of_packets_sent = transport_->number_of_rtp_packets();
// Send duplicated ACKs and mix some invalid NACKs.
for (int i = 0; i < 10; ++i) {
@@ -526,7 +530,7 @@ TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) {
video_sender_->OnReceivedCastFeedback(ack_feedback);
video_sender_->OnReceivedCastFeedback(nack_feedback);
}
- EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets());
+ EXPECT_EQ(number_of_packets_sent, transport_->number_of_rtp_packets());
// Re-transmit one packet because of duplicated ACKs.
for (int i = 0; i < 3; ++i) {
@@ -536,16 +540,16 @@ TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) {
video_sender_->OnReceivedCastFeedback(ack_feedback);
}
- transport_.SetPause(false);
+ transport_->SetPause(false);
RunTasks(100);
- EXPECT_LT(number_of_packets_sent + 1, transport_.number_of_rtp_packets());
+ EXPECT_LT(number_of_packets_sent + 1, transport_->number_of_rtp_packets());
}
TEST_F(VideoSenderTest, AcksCancelRetransmits) {
InitEncoder(false, true);
ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
- transport_.SetPause(true);
+ transport_->SetPause(true);
scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame();
video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
RunTasks(33);
@@ -556,9 +560,9 @@ TEST_F(VideoSenderTest, AcksCancelRetransmits) {
cast_feedback.ack_frame_id = 0;
video_sender_->OnReceivedCastFeedback(cast_feedback);
- transport_.SetPause(false);
+ transport_->SetPause(false);
RunTasks(33);
- EXPECT_EQ(0, transport_.number_of_rtp_packets());
+ EXPECT_EQ(0, transport_->number_of_rtp_packets());
}
TEST_F(VideoSenderTest, CheckVideoFrameFactoryIsNull) {
diff --git a/media/cast/test/cast_benchmarks.cc b/media/cast/test/cast_benchmarks.cc
index 29e2d41..3d3950e 100644
--- a/media/cast/test/cast_benchmarks.cc
+++ b/media/cast/test/cast_benchmarks.cc
@@ -71,12 +71,6 @@ namespace {
static const int64_t kStartMillisecond = INT64_C(1245);
static const int kTargetPlayoutDelayMs = 400;
-void UpdateCastTransportStatus(CastTransportStatus status) {
- bool result = (status == TRANSPORT_AUDIO_INITIALIZED ||
- status == TRANSPORT_VIDEO_INITIALIZED);
- EXPECT_TRUE(result);
-}
-
void ExpectVideoSuccess(OperationalStatus status) {
EXPECT_EQ(STATUS_INITIALIZED, status);
}
@@ -85,9 +79,6 @@ void ExpectAudioSuccess(OperationalStatus status) {
EXPECT_EQ(STATUS_INITIALIZED, status);
}
-void IgnoreRawEvents(scoped_ptr<std::vector<FrameEvent>> frame_events,
- scoped_ptr<std::vector<PacketEvent>> packet_events) {}
-
} // namespace
// Wraps a CastTransportSender and records some statistics about
@@ -168,6 +159,8 @@ class CastTransportSenderWrapper : public CastTransportSender {
rtp_receiver_statistics);
}
+ void SetOptions(const base::DictionaryValue& options) final {}
+
private:
scoped_ptr<CastTransportSender> transport_;
uint32_t audio_ssrc_, video_ssrc_;
@@ -220,8 +213,6 @@ class RunOneBenchmark {
task_runner_receiver_,
task_runner_receiver_,
task_runner_receiver_)),
- receiver_to_sender_(cast_environment_receiver_),
- sender_to_receiver_(cast_environment_sender_),
video_bytes_encoded_(0),
audio_bytes_encoded_(0),
frames_sent_(0) {
@@ -269,64 +260,7 @@ class RunOneBenchmark {
task_runner_receiver_->SetSkew(1.0 / skew);
}
- void Create(const MeasuringPoint& p) {
- net::IPEndPoint dummy_endpoint;
- transport_sender_.Init(
- new CastTransportSenderImpl(
- NULL,
- testing_clock_sender_,
- dummy_endpoint,
- dummy_endpoint,
- make_scoped_ptr(new base::DictionaryValue),
- base::Bind(&UpdateCastTransportStatus),
- base::Bind(&IgnoreRawEvents),
- base::TimeDelta::FromSeconds(1),
- task_runner_sender_,
- PacketReceiverCallback(),
- &sender_to_receiver_),
- &video_bytes_encoded_,
- &audio_bytes_encoded_);
-
- transport_receiver_.reset(
- new CastTransportSenderImpl(
- NULL,
- testing_clock_receiver_,
- dummy_endpoint,
- dummy_endpoint,
- make_scoped_ptr(new base::DictionaryValue),
- base::Bind(&UpdateCastTransportStatus),
- base::Bind(&IgnoreRawEvents),
- base::TimeDelta::FromSeconds(1),
- task_runner_receiver_,
- base::Bind(&RunOneBenchmark::ReceivePacket, base::Unretained(this)),
- &receiver_to_sender_));
-
- cast_receiver_ = CastReceiver::Create(cast_environment_receiver_,
- audio_receiver_config_,
- video_receiver_config_,
- transport_receiver_.get());
-
- cast_sender_ =
- CastSender::Create(cast_environment_sender_, &transport_sender_);
-
- cast_sender_->InitializeAudio(
- audio_sender_config_,
- base::Bind(&ExpectAudioSuccess));
- cast_sender_->InitializeVideo(
- video_sender_config_,
- base::Bind(&ExpectVideoSuccess),
- CreateDefaultVideoEncodeAcceleratorCallback(),
- CreateDefaultVideoEncodeMemoryCallback());
-
- receiver_to_sender_.Initialize(CreateSimplePipe(p),
- transport_sender_.PacketReceiverForTesting(),
- task_runner_, &testing_clock_);
- sender_to_receiver_.Initialize(
- CreateSimplePipe(p), transport_receiver_->PacketReceiverForTesting(),
- task_runner_, &testing_clock_);
-
- task_runner_->RunTasks();
- }
+ void Create(const MeasuringPoint& p);
void ReceivePacket(scoped_ptr<Packet> packet) {
cast_receiver_->ReceivePacket(std::move(packet));
@@ -484,8 +418,8 @@ class RunOneBenchmark {
scoped_refptr<CastEnvironment> cast_environment_sender_;
scoped_refptr<CastEnvironment> cast_environment_receiver_;
- LoopBackTransport receiver_to_sender_;
- LoopBackTransport sender_to_receiver_;
+ LoopBackTransport* receiver_to_sender_; // Owned by CastTransportSenderImpl.
+ LoopBackTransport* sender_to_receiver_; // Owned by CastTransportSenderImpl.
CastTransportSenderWrapper transport_sender_;
scoped_ptr<CastTransportSender> transport_receiver_;
uint64_t video_bytes_encoded_;
@@ -501,6 +435,73 @@ class RunOneBenchmark {
std::vector<std::pair<base::TimeTicks, base::TimeTicks> > video_ticks_;
};
+namespace {
+
+class TransportClient : public CastTransportSender::Client {
+ public:
+ explicit TransportClient(RunOneBenchmark* run_one_benchmark)
+ : run_one_benchmark_(run_one_benchmark) {}
+
+ void OnStatusChanged(CastTransportStatus status) final {
+ bool result = (status == TRANSPORT_AUDIO_INITIALIZED ||
+ status == TRANSPORT_VIDEO_INITIALIZED);
+ EXPECT_TRUE(result);
+ };
+ void OnLoggingEventsReceived(
+ scoped_ptr<std::vector<FrameEvent>> frame_events,
+ scoped_ptr<std::vector<PacketEvent>> packet_events) final{};
+ void ProcessRtpPacket(scoped_ptr<Packet> packet) final {
+ if (run_one_benchmark_)
+ run_one_benchmark_->ReceivePacket(std::move(packet));
+ };
+
+ private:
+ RunOneBenchmark* const run_one_benchmark_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransportClient);
+};
+
+} // namepspace
+
+void RunOneBenchmark::Create(const MeasuringPoint& p) {
+ sender_to_receiver_ = new LoopBackTransport(cast_environment_sender_);
+ transport_sender_.Init(
+ new CastTransportSenderImpl(
+ testing_clock_sender_, base::TimeDelta::FromSeconds(1),
+ make_scoped_ptr(new TransportClient(nullptr)),
+ make_scoped_ptr(sender_to_receiver_), task_runner_sender_),
+ &video_bytes_encoded_, &audio_bytes_encoded_);
+
+ receiver_to_sender_ = new LoopBackTransport(cast_environment_receiver_);
+ transport_receiver_.reset(new CastTransportSenderImpl(
+ testing_clock_receiver_, base::TimeDelta::FromSeconds(1),
+ make_scoped_ptr(new TransportClient(this)),
+ make_scoped_ptr(receiver_to_sender_), task_runner_receiver_));
+
+ cast_receiver_ =
+ CastReceiver::Create(cast_environment_receiver_, audio_receiver_config_,
+ video_receiver_config_, transport_receiver_.get());
+
+ cast_sender_ =
+ CastSender::Create(cast_environment_sender_, &transport_sender_);
+
+ cast_sender_->InitializeAudio(audio_sender_config_,
+ base::Bind(&ExpectAudioSuccess));
+ cast_sender_->InitializeVideo(video_sender_config_,
+ base::Bind(&ExpectVideoSuccess),
+ CreateDefaultVideoEncodeAcceleratorCallback(),
+ CreateDefaultVideoEncodeMemoryCallback());
+
+ receiver_to_sender_->Initialize(CreateSimplePipe(p),
+ transport_sender_.PacketReceiverForTesting(),
+ task_runner_, &testing_clock_);
+ sender_to_receiver_->Initialize(
+ CreateSimplePipe(p), transport_receiver_->PacketReceiverForTesting(),
+ task_runner_, &testing_clock_);
+
+ task_runner_->RunTasks();
+}
+
enum CacheResult { FOUND_TRUE, FOUND_FALSE, NOT_FOUND };
template <class T>
diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc
index 2dd2f93..7145ba3 100644
--- a/media/cast/test/end2end_unittest.cc
+++ b/media/cast/test/end2end_unittest.cc
@@ -94,12 +94,6 @@ std::string ConvertFromBase16String(const std::string& base_16) {
return compressed;
}
-void UpdateCastTransportStatus(CastTransportStatus status) {
- bool result = (status == TRANSPORT_AUDIO_INITIALIZED ||
- status == TRANSPORT_VIDEO_INITIALIZED);
- EXPECT_TRUE(result);
-}
-
void ExpectSuccessOperationalStatus(OperationalStatus status) {
EXPECT_EQ(STATUS_INITIALIZED, status);
}
@@ -213,6 +207,11 @@ class LoopBackTransport : public PacketSender {
int64_t GetBytesSent() final { return bytes_sent_; }
+ void StartReceiving(
+ const PacketReceiverCallbackWithStatus& packet_receiver) final {}
+
+ void StopReceiving() final {}
+
void SetSendPackets(bool send_packets) { send_packets_ = send_packets; }
void DropAllPacketsBelongingToOddFrames() {
@@ -397,6 +396,11 @@ class TestReceiverVideoCallback
// The actual test class, generate synthetic data for both audio and video and
// send those through the sender and receiver and analyzes the result.
class End2EndTest : public ::testing::Test {
+ public:
+ void ReceivePacket(scoped_ptr<media::cast::Packet> packet) {
+ cast_receiver_->ReceivePacket(std::move(packet));
+ };
+
protected:
End2EndTest()
: start_time_(),
@@ -417,8 +421,8 @@ class End2EndTest : public ::testing::Test {
task_runner_receiver_,
task_runner_receiver_,
task_runner_receiver_)),
- receiver_to_sender_(cast_environment_receiver_),
- sender_to_receiver_(cast_environment_sender_),
+ receiver_to_sender_(new LoopBackTransport(cast_environment_receiver_)),
+ sender_to_receiver_(new LoopBackTransport(cast_environment_sender_)),
test_receiver_audio_callback_(new TestReceiverAudioCallback()),
test_receiver_video_callback_(new TestReceiverVideoCallback()) {
testing_clock_.Advance(
@@ -549,68 +553,7 @@ class End2EndTest : public ::testing::Test {
}
}
- void ReceivePacket(scoped_ptr<Packet> packet) {
- cast_receiver_->ReceivePacket(std::move(packet));
- }
-
- void Create() {
- net::IPEndPoint dummy_endpoint;
- transport_sender_.reset(new CastTransportSenderImpl(
- nullptr, testing_clock_sender_, dummy_endpoint, dummy_endpoint,
- make_scoped_ptr(new base::DictionaryValue),
- base::Bind(&UpdateCastTransportStatus),
- base::Bind(&LogEventDispatcher::DispatchBatchOfEvents,
- base::Unretained(cast_environment_sender_->logger())),
- base::TimeDelta::FromMilliseconds(1), task_runner_sender_,
- PacketReceiverCallback(), &sender_to_receiver_));
-
- transport_receiver_.reset(new CastTransportSenderImpl(
- nullptr, testing_clock_sender_, dummy_endpoint, dummy_endpoint,
- make_scoped_ptr(new base::DictionaryValue),
- base::Bind(&UpdateCastTransportStatus),
- base::Bind(&LogEventDispatcher::DispatchBatchOfEvents,
- base::Unretained(cast_environment_receiver_->logger())),
- base::TimeDelta::FromMilliseconds(1), task_runner_sender_,
- base::Bind(&End2EndTest::ReceivePacket, base::Unretained(this)),
- &receiver_to_sender_));
-
- cast_receiver_ = CastReceiver::Create(cast_environment_receiver_,
- audio_receiver_config_,
- video_receiver_config_,
- transport_receiver_.get());
-
- cast_sender_ =
- CastSender::Create(cast_environment_sender_, transport_sender_.get());
-
- // Initializing audio and video senders.
- cast_sender_->InitializeAudio(
- audio_sender_config_,
- base::Bind(&ExpectSuccessOperationalStatus));
- cast_sender_->InitializeVideo(
- video_sender_config_,
- base::Bind(&ExpectSuccessOperationalStatus),
- CreateDefaultVideoEncodeAcceleratorCallback(),
- CreateDefaultVideoEncodeMemoryCallback());
- task_runner_->RunTasks();
-
- receiver_to_sender_.SetPacketReceiver(
- transport_sender_->PacketReceiverForTesting(),
- task_runner_,
- &testing_clock_);
- sender_to_receiver_.SetPacketReceiver(
- transport_receiver_->PacketReceiverForTesting(),
- task_runner_,
- &testing_clock_);
-
- audio_frame_input_ = cast_sender_->audio_frame_input();
- video_frame_input_ = cast_sender_->video_frame_input();
-
- audio_bus_factory_.reset(
- new TestAudioBusFactory(audio_sender_config_.channels,
- audio_sender_config_.frequency,
- kSoundFrequency,
- kSoundVolume));
- }
+ void Create();
~End2EndTest() override {
cast_environment_sender_->logger()->Unsubscribe(&event_subscriber_sender_);
@@ -916,8 +859,9 @@ class End2EndTest : public ::testing::Test {
scoped_refptr<CastEnvironment> cast_environment_sender_;
scoped_refptr<CastEnvironment> cast_environment_receiver_;
- LoopBackTransport receiver_to_sender_;
- LoopBackTransport sender_to_receiver_;
+ LoopBackTransport* receiver_to_sender_; // Owned by CastTransportSender.
+ LoopBackTransport* sender_to_receiver_; // Owned by CastTransportSender.
+
scoped_ptr<CastTransportSenderImpl> transport_sender_;
scoped_ptr<CastTransportSenderImpl> transport_receiver_;
@@ -940,6 +884,83 @@ class End2EndTest : public ::testing::Test {
base::MessageLoop message_loop_;
};
+namespace {
+
+class TransportClient : public CastTransportSender::Client {
+ public:
+ TransportClient(LogEventDispatcher* log_event_dispatcher,
+ End2EndTest* e2e_test)
+ : log_event_dispatcher_(log_event_dispatcher), e2e_test_(e2e_test) {}
+
+ void OnStatusChanged(media::cast::CastTransportStatus status) final {
+ bool result = (status == TRANSPORT_AUDIO_INITIALIZED ||
+ status == TRANSPORT_VIDEO_INITIALIZED);
+ EXPECT_TRUE(result);
+ };
+ void OnLoggingEventsReceived(
+ scoped_ptr<std::vector<FrameEvent>> frame_events,
+ scoped_ptr<std::vector<PacketEvent>> packet_events) final {
+ log_event_dispatcher_->DispatchBatchOfEvents(std::move(frame_events),
+ std::move(packet_events));
+ };
+ void ProcessRtpPacket(scoped_ptr<Packet> packet) final {
+ if (e2e_test_)
+ e2e_test_->ReceivePacket(std::move(packet));
+ };
+
+ private:
+ LogEventDispatcher* const log_event_dispatcher_; // Not owned by this class.
+ End2EndTest* const e2e_test_; // Not owned by this class.
+
+ DISALLOW_COPY_AND_ASSIGN(TransportClient);
+};
+
+} // namespace
+
+void End2EndTest::Create() {
+ transport_sender_.reset(new CastTransportSenderImpl(
+ testing_clock_sender_, base::TimeDelta::FromMilliseconds(1),
+ make_scoped_ptr(
+ new TransportClient(cast_environment_sender_->logger(), nullptr)),
+ make_scoped_ptr(sender_to_receiver_), task_runner_sender_));
+
+ transport_receiver_.reset(new CastTransportSenderImpl(
+ testing_clock_sender_, base::TimeDelta::FromMilliseconds(1),
+ make_scoped_ptr(
+ new TransportClient(cast_environment_receiver_->logger(), this)),
+ make_scoped_ptr(receiver_to_sender_), task_runner_sender_));
+
+ cast_receiver_ =
+ CastReceiver::Create(cast_environment_receiver_, audio_receiver_config_,
+ video_receiver_config_, transport_receiver_.get());
+
+ cast_sender_ =
+ CastSender::Create(cast_environment_sender_, transport_sender_.get());
+
+ // Initializing audio and video senders.
+ cast_sender_->InitializeAudio(audio_sender_config_,
+ base::Bind(&ExpectSuccessOperationalStatus));
+ cast_sender_->InitializeVideo(video_sender_config_,
+ base::Bind(&ExpectSuccessOperationalStatus),
+ CreateDefaultVideoEncodeAcceleratorCallback(),
+ CreateDefaultVideoEncodeMemoryCallback());
+ task_runner_->RunTasks();
+
+ receiver_to_sender_->SetPacketReceiver(
+ transport_sender_->PacketReceiverForTesting(), task_runner_,
+ &testing_clock_);
+ sender_to_receiver_->SetPacketReceiver(
+ transport_receiver_->PacketReceiverForTesting(), task_runner_,
+ &testing_clock_);
+
+ audio_frame_input_ = cast_sender_->audio_frame_input();
+ video_frame_input_ = cast_sender_->video_frame_input();
+
+ audio_bus_factory_.reset(new TestAudioBusFactory(
+ audio_sender_config_.channels, audio_sender_config_.frequency,
+ kSoundFrequency, kSoundVolume));
+}
+
TEST_F(End2EndTest, LoopWithLosslessEncoding) {
Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
Create();
@@ -980,7 +1001,7 @@ TEST_F(End2EndTest, DISABLED_StartSenderBeforeReceiver) {
int frame_number = 0;
int audio_diff = kFrameTimerMs;
- sender_to_receiver_.SetSendPackets(false);
+ sender_to_receiver_->SetSendPackets(false);
const int test_delay_ms = 100;
@@ -1015,7 +1036,7 @@ TEST_F(End2EndTest, DISABLED_StartSenderBeforeReceiver) {
}
RunTasks(test_delay_ms);
- sender_to_receiver_.SetSendPackets(true);
+ sender_to_receiver_->SetSendPackets(true);
int num_audio_frames_requested = 0;
for (int j = 0; j < 10; ++j) {
@@ -1142,8 +1163,8 @@ TEST_F(End2EndTest, SmoothPlayoutWithFivePercentClockRateSkew) {
TEST_F(End2EndTest, EvilNetwork) {
Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
- receiver_to_sender_.SetPacketPipe(test::EvilNetwork());
- sender_to_receiver_.SetPacketPipe(test::EvilNetwork());
+ receiver_to_sender_->SetPacketPipe(test::EvilNetwork());
+ sender_to_receiver_->SetPacketPipe(test::EvilNetwork());
Create();
StartBasicPlayer();
@@ -1164,8 +1185,8 @@ TEST_F(End2EndTest, EvilNetwork) {
// at a much higher frame rate.
TEST_F(End2EndTest, ShoveHighFrameRateDownYerThroat) {
Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
- receiver_to_sender_.SetPacketPipe(test::EvilNetwork());
- sender_to_receiver_.SetPacketPipe(test::EvilNetwork());
+ receiver_to_sender_->SetPacketPipe(test::EvilNetwork());
+ sender_to_receiver_->SetPacketPipe(test::EvilNetwork());
Create();
StartBasicPlayer();
@@ -1185,7 +1206,7 @@ TEST_F(End2EndTest, ShoveHighFrameRateDownYerThroat) {
TEST_F(End2EndTest, OldPacketNetwork) {
Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
- sender_to_receiver_.SetPacketPipe(test::NewRandomDrop(0.01));
+ sender_to_receiver_->SetPacketPipe(test::NewRandomDrop(0.01));
scoped_ptr<test::PacketPipe> echo_chamber(
test::NewDuplicateAndDelay(1, 10 * kFrameTimerMs));
echo_chamber->AppendToPipe(
@@ -1197,7 +1218,7 @@ TEST_F(End2EndTest, OldPacketNetwork) {
echo_chamber->AppendToPipe(
test::NewDuplicateAndDelay(1, 160 * kFrameTimerMs));
- receiver_to_sender_.SetPacketPipe(std::move(echo_chamber));
+ receiver_to_sender_->SetPacketPipe(std::move(echo_chamber));
Create();
StartBasicPlayer();
diff --git a/media/cast/test/loopback_transport.h b/media/cast/test/loopback_transport.h
index e61ae4d..7f32c6f 100644
--- a/media/cast/test/loopback_transport.h
+++ b/media/cast/test/loopback_transport.h
@@ -36,6 +36,11 @@ class LoopBackTransport : public PacketSender {
int64_t GetBytesSent() final;
+ void StartReceiving(
+ const PacketReceiverCallbackWithStatus& packet_receiver) final {}
+
+ void StopReceiving() final {}
+
// Initiailize this loopback transport.
// Establish a flow of packets from |pipe| to |packet_receiver|.
//
diff --git a/media/cast/test/sender.cc b/media/cast/test/sender.cc
index 206bfb5..fa508dc 100644
--- a/media/cast/test/sender.cc
+++ b/media/cast/test/sender.cc
@@ -160,6 +160,31 @@ void WriteStatsAndDestroySubscribers(
VLOG(0) << "Audio stats: " << json;
}
+class TransportClient : public media::cast::CastTransportSender::Client {
+ public:
+ explicit TransportClient(
+ media::cast::LogEventDispatcher* log_event_dispatcher)
+ : log_event_dispatcher_(log_event_dispatcher) {}
+
+ void OnStatusChanged(media::cast::CastTransportStatus status) final {
+ VLOG(1) << "Transport status: " << status;
+ };
+ void OnLoggingEventsReceived(
+ scoped_ptr<std::vector<media::cast::FrameEvent>> frame_events,
+ scoped_ptr<std::vector<media::cast::PacketEvent>> packet_events) final {
+ DCHECK(log_event_dispatcher_);
+ log_event_dispatcher_->DispatchBatchOfEvents(std::move(frame_events),
+ std::move(packet_events));
+ };
+ void ProcessRtpPacket(scoped_ptr<media::cast::Packet> packet) final {}
+
+ private:
+ media::cast::LogEventDispatcher* const
+ log_event_dispatcher_; // Not owned by this class.
+
+ DISALLOW_COPY_AND_ASSIGN(TransportClient);
+};
+
} // namespace
int main(int argc, char** argv) {
@@ -235,14 +260,12 @@ int main(int argc, char** argv) {
// CastTransportSender initialization.
scoped_ptr<media::cast::CastTransportSender> transport_sender =
media::cast::CastTransportSender::Create(
- nullptr, // net log.
- cast_environment->Clock(), net::IPEndPoint(), remote_endpoint,
- make_scoped_ptr(new base::DictionaryValue), // options
- base::Bind(&UpdateCastTransportStatus),
- base::Bind(&media::cast::LogEventDispatcher::DispatchBatchOfEvents,
- base::Unretained(cast_environment->logger())),
- base::TimeDelta::FromSeconds(1),
- media::cast::PacketReceiverCallback(), io_message_loop.task_runner());
+ cast_environment->Clock(), base::TimeDelta::FromSeconds(1),
+ make_scoped_ptr(new TransportClient(cast_environment->logger())),
+ make_scoped_ptr(new media::cast::UdpTransport(
+ nullptr, io_message_loop.task_runner(), net::IPEndPoint(),
+ remote_endpoint, base::Bind(&UpdateCastTransportStatus))),
+ io_message_loop.task_runner());
// Set up event subscribers.
scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber;
diff --git a/media/cast/test/simulator.cc b/media/cast/test/simulator.cc
index a2aa6e4..78c1ccf 100644
--- a/media/cast/test/simulator.cc
+++ b/media/cast/test/simulator.cc
@@ -114,10 +114,6 @@ int GetIntegerSwitchValue(const char* switch_name, int default_value) {
return as_int;
}
-void UpdateCastTransportStatus(CastTransportStatus status) {
- LOG(INFO) << "Cast transport status: " << status;
-}
-
void LogAudioOperationalStatus(OperationalStatus status) {
LOG(INFO) << "Audio status: " << status;
}
@@ -126,6 +122,44 @@ void LogVideoOperationalStatus(OperationalStatus status) {
LOG(INFO) << "Video status: " << status;
}
+struct PacketProxy {
+ PacketProxy() : receiver(NULL) {}
+ void ReceivePacket(scoped_ptr<Packet> packet) {
+ if (receiver)
+ receiver->ReceivePacket(std::move(packet));
+ }
+ CastReceiver* receiver;
+};
+
+class TransportClient : public CastTransportSender::Client {
+ public:
+ TransportClient(LogEventDispatcher* log_event_dispatcher,
+ PacketProxy* packet_proxy)
+ : log_event_dispatcher_(log_event_dispatcher),
+ packet_proxy_(packet_proxy) {}
+
+ void OnStatusChanged(CastTransportStatus status) final {
+ LOG(INFO) << "Cast transport status: " << status;
+ };
+ void OnLoggingEventsReceived(
+ scoped_ptr<std::vector<FrameEvent>> frame_events,
+ scoped_ptr<std::vector<PacketEvent>> packet_events) final {
+ DCHECK(log_event_dispatcher_);
+ log_event_dispatcher_->DispatchBatchOfEvents(std::move(frame_events),
+ std::move(packet_events));
+ };
+ void ProcessRtpPacket(scoped_ptr<Packet> packet) final {
+ if (packet_proxy_)
+ packet_proxy_->ReceivePacket(std::move(packet));
+ };
+
+ private:
+ LogEventDispatcher* const log_event_dispatcher_; // Not owned by this class.
+ PacketProxy* const packet_proxy_; // Not owned by this class.
+
+ DISALLOW_COPY_AND_ASSIGN(TransportClient);
+};
+
// Maintains a queue of encoded video frames.
// This works by tracking FRAME_CAPTURE_END and FRAME_ENCODED events.
// If a video frame is detected to be encoded it transfers a frame
@@ -345,33 +379,19 @@ void RunSimulation(const base::FilePath& source_path,
video_receiver_config.rtp_max_delay_ms =
video_sender_config.max_playout_delay.InMilliseconds();
- // Loopback transport.
- LoopBackTransport receiver_to_sender(receiver_env);
- LoopBackTransport sender_to_receiver(sender_env);
-
- struct PacketProxy {
- PacketProxy() : receiver(NULL) {}
- void ReceivePacket(scoped_ptr<Packet> packet) {
- if (receiver)
- receiver->ReceivePacket(std::move(packet));
- }
- CastReceiver* receiver;
- };
+ // Loopback transport. Owned by CastTransportSender.
+ LoopBackTransport* receiver_to_sender = new LoopBackTransport(receiver_env);
+ LoopBackTransport* sender_to_receiver = new LoopBackTransport(sender_env);
PacketProxy packet_proxy;
// Cast receiver.
scoped_ptr<CastTransportSender> transport_receiver(
new CastTransportSenderImpl(
- nullptr, &testing_clock, net::IPEndPoint(), net::IPEndPoint(),
- make_scoped_ptr(new base::DictionaryValue),
- base::Bind(&UpdateCastTransportStatus),
- base::Bind(&LogEventDispatcher::DispatchBatchOfEvents,
- base::Unretained(receiver_env->logger())),
- base::TimeDelta::FromSeconds(1), task_runner,
- base::Bind(&PacketProxy::ReceivePacket,
- base::Unretained(&packet_proxy)),
- &receiver_to_sender));
+ &testing_clock, base::TimeDelta::FromSeconds(1),
+ make_scoped_ptr(
+ new TransportClient(receiver_env->logger(), &packet_proxy)),
+ make_scoped_ptr(receiver_to_sender), task_runner));
scoped_ptr<CastReceiver> cast_receiver(
CastReceiver::Create(receiver_env,
audio_receiver_config,
@@ -382,13 +402,9 @@ void RunSimulation(const base::FilePath& source_path,
// Cast sender and transport sender.
scoped_ptr<CastTransportSender> transport_sender(new CastTransportSenderImpl(
- nullptr, &testing_clock, net::IPEndPoint(), net::IPEndPoint(),
- make_scoped_ptr(new base::DictionaryValue),
- base::Bind(&UpdateCastTransportStatus),
- base::Bind(&LogEventDispatcher::DispatchBatchOfEvents,
- base::Unretained(sender_env->logger())),
- base::TimeDelta::FromSeconds(1), task_runner, PacketReceiverCallback(),
- &sender_to_receiver));
+ &testing_clock, base::TimeDelta::FromSeconds(1),
+ make_scoped_ptr(new TransportClient(sender_env->logger(), nullptr)),
+ make_scoped_ptr(sender_to_receiver), task_runner));
scoped_ptr<CastSender> cast_sender(
CastSender::Create(sender_env, transport_sender.get()));
@@ -406,20 +422,19 @@ void RunSimulation(const base::FilePath& source_path,
ipp.reset(new test::InterruptedPoissonProcess(
average_rates,
ipp_model.coef_burstiness(), ipp_model.coef_variance(), 0));
- receiver_to_sender.Initialize(ipp->NewBuffer(128 * 1024),
- transport_sender->PacketReceiverForTesting(),
- task_runner, &testing_clock);
- sender_to_receiver.Initialize(
+ receiver_to_sender->Initialize(ipp->NewBuffer(128 * 1024),
+ transport_sender->PacketReceiverForTesting(),
+ task_runner, &testing_clock);
+ sender_to_receiver->Initialize(
ipp->NewBuffer(128 * 1024),
transport_receiver->PacketReceiverForTesting(), task_runner,
&testing_clock);
} else {
LOG(INFO) << "No network simulation.";
- receiver_to_sender.Initialize(
- scoped_ptr<test::PacketPipe>(),
- transport_sender->PacketReceiverForTesting(),
- task_runner, &testing_clock);
- sender_to_receiver.Initialize(
+ receiver_to_sender->Initialize(scoped_ptr<test::PacketPipe>(),
+ transport_sender->PacketReceiverForTesting(),
+ task_runner, &testing_clock);
+ sender_to_receiver->Initialize(
scoped_ptr<test::PacketPipe>(),
transport_receiver->PacketReceiverForTesting(), task_runner,
&testing_clock);
diff --git a/media/cast/test/utility/in_process_receiver.cc b/media/cast/test/utility/in_process_receiver.cc
index 1e97c9a..b4da3a8 100644
--- a/media/cast/test/utility/in_process_receiver.cc
+++ b/media/cast/test/utility/in_process_receiver.cc
@@ -23,6 +23,19 @@ using media::cast::UdpTransport;
namespace media {
namespace cast {
+void InProcessReceiver::TransportClient::OnStatusChanged(
+ CastTransportStatus status) {
+ LOG_IF(ERROR, status == media::cast::TRANSPORT_SOCKET_ERROR)
+ << "Transport socket error occurred. InProcessReceiver is likely "
+ "dead.";
+ VLOG(1) << "CastTransportStatus is now " << status;
+}
+
+void InProcessReceiver::TransportClient::ProcessRtpPacket(
+ scoped_ptr<Packet> packet) {
+ in_process_receiver_->ReceivePacket(std::move(packet));
+}
+
InProcessReceiver::InProcessReceiver(
const scoped_refptr<CastEnvironment>& cast_environment,
const net::IPEndPoint& local_end_point,
@@ -63,8 +76,8 @@ void InProcessReceiver::Stop() {
void InProcessReceiver::StopOnMainThread(base::WaitableEvent* event) {
DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- cast_receiver_.reset(NULL);
- transport_.reset(NULL);
+ cast_receiver_.reset(nullptr);
+ transport_.reset(nullptr);
weak_factory_.InvalidateWeakPtrs();
event->Signal();
}
@@ -81,17 +94,13 @@ void InProcessReceiver::StartOnMainThread() {
DCHECK(!transport_ && !cast_receiver_);
transport_ = CastTransportSender::Create(
- NULL,
- cast_environment_->Clock(),
- local_end_point_,
- remote_end_point_,
- scoped_ptr<base::DictionaryValue>(new base::DictionaryValue),
- base::Bind(&InProcessReceiver::UpdateCastTransportStatus,
- base::Unretained(this)),
- BulkRawEventsCallback(),
- base::TimeDelta(),
- base::Bind(&InProcessReceiver::ReceivePacket,
- base::Unretained(this)),
+ cast_environment_->Clock(), base::TimeDelta(),
+ make_scoped_ptr(new InProcessReceiver::TransportClient(this)),
+ make_scoped_ptr(new UdpTransport(
+ nullptr, cast_environment_->GetTaskRunner(CastEnvironment::MAIN),
+ local_end_point_, remote_end_point_,
+ base::Bind(&InProcessReceiver::UpdateCastTransportStatus,
+ base::Unretained(this)))),
cast_environment_->GetTaskRunner(CastEnvironment::MAIN));
cast_receiver_ = CastReceiver::Create(
diff --git a/media/cast/test/utility/in_process_receiver.h b/media/cast/test/utility/in_process_receiver.h
index cd957d4..8248ceb 100644
--- a/media/cast/test/utility/in_process_receiver.h
+++ b/media/cast/test/utility/in_process_receiver.h
@@ -33,6 +33,7 @@ namespace cast {
class CastEnvironment;
class CastReceiver;
class UdpTransport;
+class InProcessReceiver;
// Common base functionality for an in-process Cast receiver. This is meant to
// be subclassed with the OnAudioFrame() and OnVideoFrame() methods implemented,
@@ -40,6 +41,23 @@ class UdpTransport;
// rather than on the boilerplate "glue" code.
class InProcessReceiver {
public:
+ class TransportClient : public CastTransportSender::Client {
+ public:
+ explicit TransportClient(InProcessReceiver* in_process_receiver)
+ : in_process_receiver_(in_process_receiver) {}
+
+ void OnStatusChanged(CastTransportStatus status) final;
+ void OnLoggingEventsReceived(
+ scoped_ptr<std::vector<FrameEvent>> frame_events,
+ scoped_ptr<std::vector<PacketEvent>> packet_events) final {}
+ void ProcessRtpPacket(scoped_ptr<Packet> packet) final;
+
+ private:
+ InProcessReceiver* in_process_receiver_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransportClient);
+ };
+
// Construct a receiver with the given configuration. |remote_end_point| can
// be left empty, if the transport should automatically mate with the first
// remote sender it encounters.