diff options
27 files changed, 492 insertions, 125 deletions
diff --git a/chrome/browser/media/cast_transport_host_filter.cc b/chrome/browser/media/cast_transport_host_filter.cc index 807d0e1..7e2e87b 100644 --- a/chrome/browser/media/cast_transport_host_filter.cc +++ b/chrome/browser/media/cast_transport_host_filter.cc @@ -8,6 +8,13 @@ #include "chrome/browser/net/chrome_net_log.h" #include "media/cast/transport/cast_transport_sender.h" +namespace { + +// How often to send raw events. +const int kSendRawEventsIntervalSecs = 1; + +} + namespace cast { CastTransportHostFilter::CastTransportHostFilter() @@ -58,9 +65,18 @@ void CastTransportHostFilter::ReceivedRtpStatistics( channel_id, audio, sender_info, time_sent, rtp_timestamp)); } -void CastTransportHostFilter::OnNew(int32 channel_id, - const net::IPEndPoint& local_end_point, - const net::IPEndPoint& remote_end_point) { +void CastTransportHostFilter::RawEvents( + int32 channel_id, + const std::vector<media::cast::PacketEvent>& packet_events) { + if (!packet_events.empty()) + Send(new CastMsg_RawEvents(channel_id, packet_events)); +} + +void CastTransportHostFilter::OnNew( + int32 channel_id, + const net::IPEndPoint& local_end_point, + const net::IPEndPoint& remote_end_point, + const media::cast::CastLoggingConfig& logging_config) { if (id_map_.Lookup(channel_id)) { id_map_.Remove(channel_id); } @@ -71,9 +87,14 @@ void CastTransportHostFilter::OnNew(int32 channel_id, &clock_, local_end_point, remote_end_point, + logging_config, base::Bind(&CastTransportHostFilter::NotifyStatusChange, base::Unretained(this), channel_id), + base::Bind(&CastTransportHostFilter::RawEvents, + base::Unretained(this), + channel_id), + base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs), base::MessageLoopProxy::current()); sender->SetPacketReceiver(base::Bind(&CastTransportHostFilter::ReceivedPacket, diff --git a/chrome/browser/media/cast_transport_host_filter.h b/chrome/browser/media/cast_transport_host_filter.h index 2c53ab8..c644a54 100644 --- a/chrome/browser/media/cast_transport_host_filter.h +++ b/chrome/browser/media/cast_transport_host_filter.h @@ -10,6 +10,7 @@ #include "chrome/common/cast_messages.h" #include "content/public/browser/browser_message_filter.h" #include "media/cast/cast_sender.h" +#include "media/cast/logging/logging_defines.h" #include "media/cast/transport/cast_transport_sender.h" namespace cast { @@ -32,6 +33,8 @@ class CastTransportHostFilter : public content::BrowserMessageFilter { const media::cast::transport::RtcpSenderInfo& sender_info, base::TimeTicks time_sent, uint32 rtp_timestamp); + void RawEvents(int32 channel_id, + const std::vector<media::cast::PacketEvent>& packet_events); // BrowserMessageFilter implementation. virtual bool OnMessageReceived(const IPC::Message& message, @@ -65,7 +68,8 @@ class CastTransportHostFilter : public content::BrowserMessageFilter { void OnNew( int32 channel_id, const net::IPEndPoint& local_end_point, - const net::IPEndPoint& remote_end_point); + const net::IPEndPoint& remote_end_point, + const media::cast::CastLoggingConfig& logging_config); void OnDelete(int32 channel_id); IDMap<media::cast::transport::CastTransportSender, IDMapOwnPointer> id_map_; diff --git a/chrome/browser/media/cast_transport_host_filter_unittest.cc b/chrome/browser/media/cast_transport_host_filter_unittest.cc index c7139a4..81f4c61 100644 --- a/chrome/browser/media/cast_transport_host_filter_unittest.cc +++ b/chrome/browser/media/cast_transport_host_filter_unittest.cc @@ -7,6 +7,7 @@ #include "base/time/default_tick_clock.h" #include "chrome/browser/media/cast_transport_host_filter.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "media/cast/logging/logging_defines.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -15,7 +16,9 @@ class CastTransportHostFilterTest : public testing::Test { public: CastTransportHostFilterTest() : browser_thread_bundle_( - content::TestBrowserThreadBundle::IO_MAINLOOP) { + content::TestBrowserThreadBundle::IO_MAINLOOP), + logging_config_( + media::cast::GetLoggingConfigWithRawEventsAndStatsEnabled()) { filter_ = new cast::CastTransportHostFilter(); local_endpoint_ = net::IPEndPoint(net::IPAddressNumber(4, 0), 0); // 127.0.0.1:7 is the local echo service port, which @@ -40,11 +43,13 @@ class CastTransportHostFilterTest : public testing::Test { net::IPAddressNumber receiver_address_; net::IPEndPoint local_endpoint_; net::IPEndPoint receive_endpoint_; + media::cast::CastLoggingConfig logging_config_; }; TEST_F(CastTransportHostFilterTest, NewDelete) { const int kChannelId = 17; - CastHostMsg_New new_msg(kChannelId, local_endpoint_, receive_endpoint_); + CastHostMsg_New new_msg(kChannelId, local_endpoint_, receive_endpoint_, + logging_config_); CastHostMsg_Delete delete_msg(kChannelId); // New, then delete, as expected. @@ -67,7 +72,8 @@ TEST_F(CastTransportHostFilterTest, NewDelete) { TEST_F(CastTransportHostFilterTest, NewMany) { for (int i = 0; i < 100; i++) { - CastHostMsg_New new_msg(i, local_endpoint_, receive_endpoint_); + CastHostMsg_New new_msg(i, local_endpoint_, receive_endpoint_, + logging_config_); FakeSend(new_msg); } @@ -82,7 +88,8 @@ TEST_F(CastTransportHostFilterTest, NewMany) { TEST_F(CastTransportHostFilterTest, SimpleMessages) { // Create a cast transport sender. const int32 kChannelId = 42; - CastHostMsg_New new_msg(kChannelId, local_endpoint_, receive_endpoint_); + CastHostMsg_New new_msg(kChannelId, local_endpoint_, receive_endpoint_, + logging_config_); FakeSend(new_msg); media::cast::transport::CastTransportAudioConfig audio_config; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index ccc9de1..62cb6d7 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -62,6 +62,7 @@ '../google_apis/gcm/gcm.gyp:gcm', '../google_apis/google_apis.gyp:google_apis', '../jingle/jingle.gyp:notifier', + '../media/cast/logging/logging.gyp:cast_common_logging', '../media/cast/transport/cast_transport.gyp:cast_transport', '../skia/skia.gyp:skia', '../sql/sql.gyp:sql', diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index 8ef45c8..b57fc7f 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -22,8 +22,8 @@ '../components/components.gyp:visitedlink_renderer', '../content/content.gyp:content_renderer', '../media/cast/cast.gyp:cast_config', - '../media/cast/cast.gyp:sender_logging', '../media/cast/cast_sender.gyp:cast_sender', + '../media/cast/logging/logging.gyp:sender_logging', '../media/cast/transport/cast_transport.gyp:cast_transport', '../net/net.gyp:net', '../skia/skia.gyp:skia', diff --git a/chrome/common/cast_messages.h b/chrome/common/cast_messages.h index 404a26f..51f4e54 100644 --- a/chrome/common/cast_messages.h +++ b/chrome/common/cast_messages.h @@ -7,6 +7,7 @@ #include "ipc/ipc_message_macros.h" #include "media/cast/cast_sender.h" +#include "media/cast/logging/logging_defines.h" #include "media/cast/rtcp/rtcp_defines.h" #include "media/cast/transport/cast_transport_sender.h" #include "net/base/ip_endpoint.h" @@ -24,6 +25,8 @@ IPC_ENUM_TRAITS_MAX_VALUE(media::cast::transport::RtcpSenderFrameStatus, media::cast::transport::kRtcpSenderFrameStatusLast) IPC_ENUM_TRAITS_MAX_VALUE(media::cast::transport::CastTransportStatus, media::cast::transport::CAST_TRANSPORT_STATUS_LAST) +IPC_ENUM_TRAITS_MAX_VALUE(media::cast::CastLoggingEvent, + media::cast::kNumOfLoggingEvents) IPC_STRUCT_TRAITS_BEGIN(media::cast::transport::EncodedAudioFrame) IPC_STRUCT_TRAITS_MEMBER(codec) @@ -90,6 +93,21 @@ IPC_STRUCT_TRAITS_BEGIN(media::cast::transport::SendRtcpFromRtpSenderData) IPC_STRUCT_TRAITS_MEMBER(c_name) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(media::cast::PacketEvent) + IPC_STRUCT_TRAITS_MEMBER(rtp_timestamp) + IPC_STRUCT_TRAITS_MEMBER(frame_id) + IPC_STRUCT_TRAITS_MEMBER(max_packet_id) + IPC_STRUCT_TRAITS_MEMBER(packet_id) + IPC_STRUCT_TRAITS_MEMBER(size) + IPC_STRUCT_TRAITS_MEMBER(timestamp) + IPC_STRUCT_TRAITS_MEMBER(type) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(media::cast::CastLoggingConfig) + IPC_STRUCT_TRAITS_MEMBER(enable_raw_data_collection) + IPC_STRUCT_TRAITS_MEMBER(enable_stats_data_collection) + IPC_STRUCT_TRAITS_MEMBER(enable_tracing) +IPC_STRUCT_TRAITS_END() // Cast messages sent from the browser to the renderer. @@ -110,6 +128,9 @@ IPC_MESSAGE_CONTROL5( base::TimeTicks /* time_sent */, uint32 /* rtp_timestamp */); +IPC_MESSAGE_CONTROL2(CastMsg_RawEvents, + int32 /* channel_id */, + std::vector<media::cast::PacketEvent> /* packet_events */); // Cast messages sent from the renderer to the browser. @@ -149,11 +170,12 @@ IPC_MESSAGE_CONTROL3( bool /* is_audio */, media::cast::MissingFramesAndPacketsMap /* missing_packets */) -IPC_MESSAGE_CONTROL3( +IPC_MESSAGE_CONTROL4( CastHostMsg_New, int32 /* channel_id */, net::IPEndPoint /*local_end_point*/, - net::IPEndPoint /*remote_end_point*/); + net::IPEndPoint /*remote_end_point*/, + media::cast::CastLoggingConfig /* logging_config */); IPC_MESSAGE_CONTROL1( CastHostMsg_Delete, diff --git a/chrome/renderer/media/cast_ipc_dispatcher.cc b/chrome/renderer/media/cast_ipc_dispatcher.cc index feff41d..022d7ec 100644 --- a/chrome/renderer/media/cast_ipc_dispatcher.cc +++ b/chrome/renderer/media/cast_ipc_dispatcher.cc @@ -51,6 +51,7 @@ bool CastIPCDispatcher::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(CastMsg_ReceivedPacket, OnReceivedPacket) IPC_MESSAGE_HANDLER(CastMsg_NotifyStatusChange, OnNotifyStatusChange) IPC_MESSAGE_HANDLER(CastMsg_RtpStatistics, OnRtpStatistics) + IPC_MESSAGE_HANDLER(CastMsg_RawEvents, OnRawEvents) IPC_MESSAGE_UNHANDLED(handled = false); IPC_END_MESSAGE_MAP(); return handled; @@ -82,8 +83,8 @@ void CastIPCDispatcher::OnReceivedPacket( if (sender) { sender->OnReceivedPacket(packet); } else { - LOG(ERROR) << "CastIPCDispatcher::OnReceivedPacket " - << "on non-existing channel."; + DVLOG(1) << "CastIPCDispatcher::OnReceivedPacket " + << "on non-existing channel."; } } @@ -94,7 +95,7 @@ void CastIPCDispatcher::OnNotifyStatusChange( if (sender) { sender->OnNotifyStatusChange(status); } else { - LOG(ERROR) + DVLOG(1) << "CastIPCDispatcher::OnNotifystatusChange on non-existing channel."; } } @@ -109,7 +110,17 @@ void CastIPCDispatcher::OnRtpStatistics( if (sender) { sender->OnRtpStatistics(audio, sender_info, time_sent, rtp_timestamp); } else { - LOG(ERROR) - << "CastIPCDispatcher::OnNotifystatusChange on non-existing channel."; + DVLOG(1) << "CastIPCDispatcher::OnRtpStatistics on non-existing channel."; + } +} + +void CastIPCDispatcher::OnRawEvents( + int32 channel_id, + const std::vector<media::cast::PacketEvent>& packet_events) { + CastTransportSenderIPC* sender = id_map_.Lookup(channel_id); + if (sender) { + sender->OnRawEvents(packet_events); + } else { + DVLOG(1) << "CastIPCDispatcher::OnRawEvents on non-existing channel."; } } diff --git a/chrome/renderer/media/cast_ipc_dispatcher.h b/chrome/renderer/media/cast_ipc_dispatcher.h index 7464f4d..4e87f2e 100644 --- a/chrome/renderer/media/cast_ipc_dispatcher.h +++ b/chrome/renderer/media/cast_ipc_dispatcher.h @@ -9,6 +9,7 @@ #include "base/id_map.h" #include "ipc/ipc_channel_proxy.h" #include "media/cast/cast_sender.h" +#include "media/cast/logging/logging_defines.h" #include "media/cast/transport/cast_transport_sender.h" class CastTransportSenderIPC; @@ -45,6 +46,8 @@ class CastIPCDispatcher : public IPC::ChannelProxy::MessageFilter { const media::cast::transport::RtcpSenderInfo& sender_info, base::TimeTicks time_sent, uint32 rtp_timestamp); + void OnRawEvents(int32 channel_id, + const std::vector<media::cast::PacketEvent>& packet_events); static CastIPCDispatcher* global_instance_; diff --git a/chrome/renderer/media/cast_session_delegate.cc b/chrome/renderer/media/cast_session_delegate.cc index f72c682..4340ab7 100644 --- a/chrome/renderer/media/cast_session_delegate.cc +++ b/chrome/renderer/media/cast_session_delegate.cc @@ -63,14 +63,14 @@ CastSessionDelegate::~CastSessionDelegate() { } } -void CastSessionDelegate::Initialize() { +void CastSessionDelegate::Initialize( + const media::cast::CastLoggingConfig& logging_config) { if (cast_environment_) return; // Already initialized. // CastSender uses the renderer's IO thread as the main thread. This reduces // thread hopping for incoming video frames and outgoing network packets. // There's no need to decode so no thread assigned for decoding. - // Logging: enable raw events and stats collection. cast_environment_ = new CastEnvironment( scoped_ptr<base::TickClock>(new base::DefaultTickClock()).Pass(), base::MessageLoopProxy::current(), @@ -79,7 +79,7 @@ void CastSessionDelegate::Initialize() { g_cast_threads.Get().GetVideoEncodeMessageLoopProxy(), NULL, base::MessageLoopProxy::current(), - media::cast::GetLoggingConfigWithRawEventsAndStatsEnabled()); + logging_config); } void CastSessionDelegate::StartAudio( @@ -198,7 +198,10 @@ void CastSessionDelegate::StartSendingInternal() { if (!audio_config_ || !video_config_) return; - Initialize(); + // Logging: enable raw events and stats collection. + media::cast::CastLoggingConfig logging_config = + media::cast::GetLoggingConfigWithRawEventsAndStatsEnabled(); + Initialize(logging_config); // Rationale for using unretained: The callback cannot be called after the // destruction of CastTransportSenderIPC, and they both share the same thread. @@ -206,6 +209,9 @@ void CastSessionDelegate::StartSendingInternal() { local_endpoint_, remote_endpoint_, base::Bind(&CastSessionDelegate::StatusNotificationCB, + base::Unretained(this)), + logging_config, + base::Bind(&CastSessionDelegate::LogRawEvents, base::Unretained(this)))); // TODO(hubbe): set config.aes_key and config.aes_iv_mask. @@ -252,3 +258,20 @@ void CastSessionDelegate::InitializationResult( } } +void CastSessionDelegate::LogRawEvents( + const std::vector<media::cast::PacketEvent>& packet_events) { + DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); + + for (std::vector<media::cast::PacketEvent>::const_iterator it = + packet_events.begin(); + it != packet_events.end(); + ++it) { + cast_environment_->Logging()->InsertPacketEvent(it->timestamp, + it->type, + it->rtp_timestamp, + it->frame_id, + it->packet_id, + it->max_packet_id, + it->size); + } +} diff --git a/chrome/renderer/media/cast_session_delegate.h b/chrome/renderer/media/cast_session_delegate.h index 05d1366..9c9767a 100644 --- a/chrome/renderer/media/cast_session_delegate.h +++ b/chrome/renderer/media/cast_session_delegate.h @@ -17,6 +17,7 @@ #include "base/time/default_tick_clock.h" #include "media/cast/cast_config.h" #include "media/cast/cast_sender.h" +#include "media/cast/logging/logging_defines.h" namespace base { class MessageLoopProxy; @@ -72,7 +73,7 @@ class CastSessionDelegate { private: // Start encoding threads and initialize the CastEnvironment. - void Initialize(); + void Initialize(const media::cast::CastLoggingConfig& logging_config); // Configure CastSender. It is ready to accept audio / video frames after // receiving a successful call to InitializationResult. @@ -81,6 +82,9 @@ class CastSessionDelegate { void StatusNotificationCB( media::cast::transport::CastTransportStatus status); + // Adds logs collected from transport on browser side. + void LogRawEvents(const std::vector<media::cast::PacketEvent>& packet_events); + base::ThreadChecker thread_checker_; scoped_refptr<media::cast::CastEnvironment> cast_environment_; scoped_ptr<media::cast::CastSender> cast_sender_; diff --git a/chrome/renderer/media/cast_transport_sender_ipc.cc b/chrome/renderer/media/cast_transport_sender_ipc.cc index 7b59693..c4ccd44 100644 --- a/chrome/renderer/media/cast_transport_sender_ipc.cc +++ b/chrome/renderer/media/cast_transport_sender_ipc.cc @@ -15,12 +15,15 @@ CastTransportSenderIPC::CastTransportSenderIPC( const net::IPEndPoint& local_end_point, const net::IPEndPoint& remote_end_point, - const media::cast::transport::CastTransportStatusCallback& status_cb) - : status_callback_(status_cb) { + const media::cast::transport::CastTransportStatusCallback& status_cb, + const media::cast::CastLoggingConfig& logging_config, + const media::cast::transport::BulkRawEventsCallback& raw_events_cb) + : status_callback_(status_cb), raw_events_callback_(raw_events_cb) { if (CastIPCDispatcher::Get()) { channel_id_ = CastIPCDispatcher::Get()->AddSender(this); } - Send(new CastHostMsg_New(channel_id_, local_end_point, remote_end_point)); + Send(new CastHostMsg_New(channel_id_, local_end_point, remote_end_point, + logging_config)); } CastTransportSenderIPC::~CastTransportSenderIPC() { @@ -107,8 +110,7 @@ void CastTransportSenderIPC::OnReceivedPacket( new media::cast::transport::Packet(packet)); packet_callback_.Run(packet_copy.Pass()); } else { - LOG(ERROR) << "CastIPCDispatcher::OnReceivedPacket " - << "no packet callback yet."; + DVLOG(1) << "CastIPCDispatcher::OnReceivedPacket no packet callback yet."; } } @@ -127,6 +129,11 @@ void CastTransportSenderIPC::OnRtpStatistics( callback.Run(sender_info, time_sent, rtp_timestamp); } +void CastTransportSenderIPC::OnRawEvents( + const std::vector<media::cast::PacketEvent>& packet_events) { + raw_events_callback_.Run(packet_events); +} + void CastTransportSenderIPC::Send(IPC::Message* message) { if (CastIPCDispatcher::Get()) { CastIPCDispatcher::Get()->Send(message); diff --git a/chrome/renderer/media/cast_transport_sender_ipc.h b/chrome/renderer/media/cast_transport_sender_ipc.h index ba7a3d3..089f1fa 100644 --- a/chrome/renderer/media/cast_transport_sender_ipc.h +++ b/chrome/renderer/media/cast_transport_sender_ipc.h @@ -7,6 +7,7 @@ #include "base/message_loop/message_loop_proxy.h" #include "ipc/ipc_channel_proxy.h" +#include "media/cast/logging/logging_defines.h" #include "media/cast/transport/cast_transport_sender.h" // This implementation of the CastTransportSender interface @@ -20,7 +21,9 @@ class CastTransportSenderIPC CastTransportSenderIPC( const net::IPEndPoint& local_end_point, const net::IPEndPoint& remote_end_point, - const media::cast::transport::CastTransportStatusCallback& status_cb); + const media::cast::transport::CastTransportStatusCallback& status_cb, + const media::cast::CastLoggingConfig& logging_config, + const media::cast::transport::BulkRawEventsCallback& raw_events_cb); virtual ~CastTransportSenderIPC(); @@ -64,6 +67,7 @@ class CastTransportSenderIPC const media::cast::transport::RtcpSenderInfo& sender_info, base::TimeTicks time_sent, uint32 rtp_timestamp); + void OnRawEvents(const std::vector<media::cast::PacketEvent>& packet_events); private: void Send(IPC::Message* message); @@ -73,6 +77,8 @@ class CastTransportSenderIPC media::cast::transport::CastTransportStatusCallback status_callback_; media::cast::transport::CastTransportRtpStatistics audio_rtp_callback_; media::cast::transport::CastTransportRtpStatistics video_rtp_callback_; + media::cast::transport::BulkRawEventsCallback raw_events_callback_; + DISALLOW_COPY_AND_ASSIGN(CastTransportSenderIPC); }; diff --git a/media/cast/audio_sender/audio_sender_unittest.cc b/media/cast/audio_sender/audio_sender_unittest.cc index 8db06cb..c7ce707 100644 --- a/media/cast/audio_sender/audio_sender_unittest.cc +++ b/media/cast/audio_sender/audio_sender_unittest.cc @@ -61,6 +61,7 @@ class AudioSenderTest : public ::testing::Test { testing_clock_->Advance( base::TimeDelta::FromMilliseconds(kStartMillisecond)); task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_); + CastLoggingConfig logging_config = GetDefaultCastSenderLoggingConfig(); cast_environment_ = new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(), task_runner_, @@ -69,7 +70,7 @@ class AudioSenderTest : public ::testing::Test { task_runner_, task_runner_, task_runner_, - GetDefaultCastSenderLoggingConfig()); + logging_config); audio_config_.codec = transport::kOpus; audio_config_.use_external_encoder = false; audio_config_.frequency = kDefaultAudioSamplingRate; @@ -87,7 +88,10 @@ class AudioSenderTest : public ::testing::Test { testing_clock_, dummy_endpoint, dummy_endpoint, + logging_config, base::Bind(&UpdateCastTransportStatus), + transport::BulkRawEventsCallback(), + base::TimeDelta(), task_runner_, &transport_)); transport_sender_->InitializeAudio(transport_config); diff --git a/media/cast/cast.gyp b/media/cast/cast.gyp index 33ac3f4..e0d0c69 100644 --- a/media/cast/cast.gyp +++ b/media/cast/cast.gyp @@ -23,70 +23,6 @@ 'cast_defines.h', 'cast_environment.cc', 'cast_environment.h', - 'logging/logging_defines.cc', - 'logging/logging_defines.h', - 'logging/logging_impl.cc', - 'logging/logging_impl.h', - 'logging/logging_raw.cc', - 'logging/logging_raw.h', - 'logging/logging_stats.cc', - 'logging/logging_stats.h', - 'logging/raw_event_subscriber.h', - 'logging/simple_event_subscriber.cc', - 'logging/simple_event_subscriber.h', - ], # source - }, - { - 'target_name': 'cast_logging_proto_lib', - 'type': 'static_library', - 'sources': [ - 'logging/proto/proto_utils.cc', - 'logging/proto/raw_events.proto', - ], - 'variables': { - 'proto_in_dir': 'logging/proto', - 'proto_out_dir': 'media/cast/logging/proto', - }, - 'includes': ['../../build/protoc.gypi'], - }, - { - 'target_name': 'sender_logging', - 'type': 'static_library', - 'include_dirs': [ - '<(DEPTH)/', - ], - 'dependencies': [ - 'cast_config', - 'cast_logging_proto_lib', - '<(DEPTH)/base/base.gyp:base', - ], - 'export_dependent_settings': [ - 'cast_logging_proto_lib', - ], - 'sources': [ - 'logging/encoding_event_subscriber.cc', - 'logging/encoding_event_subscriber.h', - 'logging/log_serializer.cc', - 'logging/log_serializer.h', - ], # source - }, - { - 'target_name': 'cast_log_analysis', - 'type': 'static_library', - 'include_dirs': [ - '<(DEPTH)/', - ], - 'dependencies': [ - 'cast_config', - 'cast_logging_proto_lib', - '<(DEPTH)/base/base.gyp:base', - ], - 'export_dependent_settings': [ - 'cast_logging_proto_lib', - ], - 'sources': [ - 'logging/log_deserializer.cc', - 'logging/log_deserializer.h', ], # source }, ], # targets, @@ -98,11 +34,11 @@ 'type': '<(gtest_target_type)', 'dependencies': [ 'cast_config', - 'cast_log_analysis', - 'cast_logging_proto_lib', 'cast_receiver.gyp:cast_receiver', 'cast_sender.gyp:cast_sender', - 'sender_logging', + 'logging/logging.gyp:cast_log_analysis', + 'logging/logging.gyp:cast_logging_proto_lib', + 'logging/logging.gyp:sender_logging', 'test/utility/utility.gyp:cast_test_utility', 'transport/cast_transport.gyp:cast_transport', '<(DEPTH)/base/base.gyp:test_support_base', @@ -153,6 +89,7 @@ 'test/fake_single_thread_task_runner.h', 'test/fake_video_encode_accelerator.cc', 'test/fake_video_encode_accelerator.h', + 'transport/cast_transport_sender_impl_unittest.cc', 'transport/pacing/mock_paced_packet_sender.cc', 'transport/pacing/mock_paced_packet_sender.h', 'transport/pacing/paced_sender_unittest.cc', @@ -176,7 +113,7 @@ ], 'dependencies': [ 'cast_config', - 'sender_logging', + 'logging/logging.gyp:sender_logging', '<(DEPTH)/ui/gfx/gfx.gyp:gfx', '<(DEPTH)/net/net.gyp:net_test_support', '<(DEPTH)/media/cast/cast_sender.gyp:*', diff --git a/media/cast/logging/logging.gyp b/media/cast/logging/logging.gyp new file mode 100644 index 0000000..ba2c2dc --- /dev/null +++ b/media/cast/logging/logging.gyp @@ -0,0 +1,87 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'targets': [ + { + 'target_name': 'cast_common_logging', + 'type': 'static_library', + 'include_dirs': [ + '<(DEPTH)/', + ], + 'dependencies': [ + 'cast_logging_proto_lib', + '<(DEPTH)/base/base.gyp:base', + ], + 'export_dependent_settings': [ + 'cast_logging_proto_lib', + ], + 'sources': [ + 'logging_defines.cc', + 'logging_defines.h', + 'logging_impl.cc', + 'logging_impl.h', + 'logging_raw.cc', + 'logging_raw.h', + 'logging_stats.cc', + 'logging_stats.h', + 'raw_event_subscriber.h', + 'simple_event_subscriber.cc', + 'simple_event_subscriber.h', + ], # source + }, + { + 'target_name': 'sender_logging', + 'type': 'static_library', + 'include_dirs': [ + '<(DEPTH)/', + ], + 'dependencies': [ + 'cast_common_logging', + 'cast_logging_proto_lib', + '<(DEPTH)/base/base.gyp:base', + ], + 'export_dependent_settings': [ + 'cast_logging_proto_lib', + ], + 'sources': [ + 'encoding_event_subscriber.cc', + 'encoding_event_subscriber.h', + 'log_serializer.cc', + 'log_serializer.h', + ], # source + }, + { + 'target_name': 'cast_logging_proto_lib', + 'type': 'static_library', + 'sources': [ + 'proto/proto_utils.cc', + 'proto/raw_events.proto', + ], + 'variables': { + 'proto_in_dir': 'proto', + 'proto_out_dir': 'media/cast/logging/proto', + }, + 'includes': ['../../../build/protoc.gypi'], + }, + { + 'target_name': 'cast_log_analysis', + 'type': 'static_library', + 'include_dirs': [ + '<(DEPTH)/', + ], + 'dependencies': [ + 'cast_logging_proto_lib', + 'sender_logging', + '<(DEPTH)/base/base.gyp:base', + ], + 'export_dependent_settings': [ + 'cast_logging_proto_lib', + ], + 'sources': [ + 'log_deserializer.cc', + 'log_deserializer.h', + ], # source + }, + ], +} diff --git a/media/cast/logging/logging_defines.cc b/media/cast/logging/logging_defines.cc index 5adb574..b82072a 100644 --- a/media/cast/logging/logging_defines.cc +++ b/media/cast/logging/logging_defines.cc @@ -65,9 +65,6 @@ std::string CastLoggingToString(CastLoggingEvent event) { ENUM_TO_STRING(VideoPacketReceived); ENUM_TO_STRING(DuplicateAudioPacketReceived); ENUM_TO_STRING(DuplicateVideoPacketReceived); - case kNumOfLoggingEvents: - NOTREACHED(); - return ""; } NOTREACHED(); return ""; @@ -105,9 +102,6 @@ EventMediaType GetEventMediaType(CastLoggingEvent event) { case kVideoPacketReceived: case kDuplicateVideoPacketReceived: return VIDEO_EVENT; - case kNumOfLoggingEvents: - NOTREACHED(); - return OTHER_EVENT; } NOTREACHED(); return OTHER_EVENT; diff --git a/media/cast/logging/logging_defines.h b/media/cast/logging/logging_defines.h index 10529a2..675f751 100644 --- a/media/cast/logging/logging_defines.h +++ b/media/cast/logging/logging_defines.h @@ -71,7 +71,7 @@ enum CastLoggingEvent { kVideoPacketReceived, kDuplicateAudioPacketReceived, kDuplicateVideoPacketReceived, - kNumOfLoggingEvents, + kNumOfLoggingEvents = kDuplicateVideoPacketReceived }; std::string CastLoggingToString(CastLoggingEvent event); diff --git a/media/cast/logging/proto/proto_utils.cc b/media/cast/logging/proto/proto_utils.cc index 5805ddc..4b97295 100644 --- a/media/cast/logging/proto/proto_utils.cc +++ b/media/cast/logging/proto/proto_utils.cc @@ -43,9 +43,6 @@ media::cast::proto::EventType ToProtoEventType(CastLoggingEvent event) { DUPLICATE_AUDIO_PACKET_RECEIVED); TO_PROTO_ENUM(kDuplicateVideoPacketReceived, DUPLICATE_VIDEO_PACKET_RECEIVED); - case kNumOfLoggingEvents: - NOTREACHED(); - return media::cast::proto::UNKNOWN; } NOTREACHED(); return media::cast::proto::UNKNOWN; diff --git a/media/cast/rtcp/rtcp_unittest.cc b/media/cast/rtcp/rtcp_unittest.cc index 9ee0523..ac7144c 100644 --- a/media/cast/rtcp/rtcp_unittest.cc +++ b/media/cast/rtcp/rtcp_unittest.cc @@ -145,6 +145,7 @@ class RtcpTest : public ::testing::Test { RtcpTest() : testing_clock_(new base::SimpleTestTickClock()), task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)), + logging_config_(GetDefaultCastSenderLoggingConfig()), cast_environment_(new CastEnvironment( scoped_ptr<base::TickClock>(testing_clock_).Pass(), task_runner_, @@ -153,7 +154,7 @@ class RtcpTest : public ::testing::Test { task_runner_, task_runner_, task_runner_, - GetDefaultCastSenderLoggingConfig())), + logging_config_)), sender_to_receiver_(testing_clock_), receiver_to_sender_(cast_environment_, testing_clock_) { testing_clock_->Advance( @@ -164,7 +165,10 @@ class RtcpTest : public ::testing::Test { testing_clock_, dummy_endpoint, dummy_endpoint, + logging_config_, base::Bind(&UpdateCastTransportStatus), + transport::BulkRawEventsCallback(), + base::TimeDelta(), task_runner_, &sender_to_receiver_)); EXPECT_CALL(mock_sender_feedback_, OnReceivedCastFeedback(_)).Times(0); @@ -188,6 +192,7 @@ class RtcpTest : public ::testing::Test { base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; + CastLoggingConfig logging_config_; scoped_refptr<CastEnvironment> cast_environment_; RtcpTestPacketSender sender_to_receiver_; scoped_ptr<transport::CastTransportSenderImpl> transport_sender_; diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc index 70f7c46..1524c8f 100644 --- a/media/cast/test/end2end_unittest.cc +++ b/media/cast/test/end2end_unittest.cc @@ -398,6 +398,7 @@ class End2EndTest : public ::testing::Test { testing_clock_receiver_(new base::SimpleTestTickClock()), task_runner_(new test::FakeSingleThreadTaskRunner( testing_clock_sender_)), + logging_config_(GetLoggingConfigWithRawEventsAndStatsEnabled()), cast_environment_sender_(new CastEnvironment( scoped_ptr<base::TickClock>(testing_clock_sender_).Pass(), task_runner_, @@ -406,7 +407,7 @@ class End2EndTest : public ::testing::Test { task_runner_, task_runner_, task_runner_, - GetLoggingConfigWithRawEventsAndStatsEnabled())), + logging_config_)), cast_environment_receiver_(new CastEnvironment( scoped_ptr<base::TickClock>(testing_clock_receiver_).Pass(), task_runner_, @@ -415,7 +416,7 @@ class End2EndTest : public ::testing::Test { task_runner_, task_runner_, task_runner_, - GetLoggingConfigWithRawEventsAndStatsEnabled())), + logging_config_)), receiver_to_sender_(cast_environment_receiver_), sender_to_receiver_(cast_environment_sender_), test_receiver_audio_callback_(new TestReceiverAudioCallback()), @@ -502,7 +503,10 @@ class End2EndTest : public ::testing::Test { testing_clock_sender_, dummy_endpoint, dummy_endpoint, + logging_config_, base::Bind(&UpdateCastTransportStatus), + base::Bind(&End2EndTest::LogRawEvents, base::Unretained(this)), + base::TimeDelta::FromSeconds(1), task_runner_, &sender_to_receiver_)); transport_sender_->InitializeAudio(transport_audio_config_); @@ -567,6 +571,22 @@ class End2EndTest : public ::testing::Test { EXPECT_EQ(result, STATUS_INITIALIZED); } + void LogRawEvents(const std::vector<PacketEvent>& packet_events) { + EXPECT_FALSE(packet_events.empty()); + for (std::vector<media::cast::PacketEvent>::const_iterator it = + packet_events.begin(); + it != packet_events.end(); + ++it) { + cast_environment_sender_->Logging()->InsertPacketEvent(it->timestamp, + it->type, + it->rtp_timestamp, + it->frame_id, + it->packet_id, + it->max_packet_id, + it->size); + } + } + AudioReceiverConfig audio_receiver_config_; VideoReceiverConfig video_receiver_config_; AudioSenderConfig audio_sender_config_; @@ -578,6 +598,7 @@ class End2EndTest : public ::testing::Test { base::SimpleTestTickClock* testing_clock_sender_; base::SimpleTestTickClock* testing_clock_receiver_; scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; + CastLoggingConfig logging_config_; scoped_refptr<CastEnvironment> cast_environment_sender_; scoped_refptr<CastEnvironment> cast_environment_receiver_; @@ -599,6 +620,9 @@ class End2EndTest : public ::testing::Test { std::vector<FrameEvent> frame_events_; std::vector<PacketEvent> packet_events_; std::vector<GenericEvent> generic_events_; + + // |transport_sender_| has a RepeatingTimer which needs a MessageLoop. + base::MessageLoop message_loop_; }; TEST_F(End2EndTest, LoopNoLossPcm16) { diff --git a/media/cast/test/sender.cc b/media/cast/test/sender.cc index af369eb..7a0ff7e 100644 --- a/media/cast/test/sender.cc +++ b/media/cast/test/sender.cc @@ -317,6 +317,24 @@ namespace { void UpdateCastTransportStatus( media::cast::transport::CastTransportStatus status) {} +void LogRawEvents( + const scoped_refptr<media::cast::CastEnvironment>& cast_environment, + const std::vector<media::cast::PacketEvent>& packet_events) { + VLOG(1) << "Got packet events from transport, size: " << packet_events.size(); + for (std::vector<media::cast::PacketEvent>::const_iterator it = + packet_events.begin(); + it != packet_events.end(); + ++it) { + cast_environment->Logging()->InsertPacketEvent(it->timestamp, + it->type, + it->rtp_timestamp, + it->frame_id, + it->packet_id, + it->max_packet_id, + it->size); + } +} + void InitializationResult(media::cast::CastInitializationStatus result) { CHECK_EQ(result, media::cast::STATUS_INITIALIZED); VLOG(1) << "Cast Sender initialized"; @@ -410,6 +428,11 @@ int main(int argc, char** argv) { media::cast::VideoSenderConfig video_config = media::cast::GetVideoSenderConfig(); + // Enable main and send side threads only. Enable raw event logging. + // Running transport on the main thread. + media::cast::CastLoggingConfig logging_config; + logging_config.enable_raw_data_collection = true; + // Setting up transport config. media::cast::transport::CastTransportAudioConfig transport_audio_config; media::cast::transport::CastTransportVideoConfig transport_video_config; @@ -421,18 +444,6 @@ int main(int argc, char** argv) { transport_video_config.base.ssrc = video_config.sender_ssrc; transport_video_config.base.rtp_config = video_config.rtp_config; - scoped_ptr<media::cast::transport::CastTransportSender> transport_sender = - media::cast::transport::CastTransportSender::Create( - NULL, // net log. - clock.get(), - local_endpoint, - remote_endpoint, - base::Bind(&UpdateCastTransportStatus), - io_message_loop.message_loop_proxy()); - - transport_sender->InitializeAudio(transport_audio_config); - transport_sender->InitializeVideo(transport_video_config); - // Enable main and send side threads only. Enable raw event and stats logging. // Running transport on the main thread. scoped_refptr<media::cast::CastEnvironment> cast_environment( @@ -446,6 +457,21 @@ int main(int argc, char** argv) { io_message_loop.message_loop_proxy(), media::cast::GetLoggingConfigWithRawEventsAndStatsEnabled())); + scoped_ptr<media::cast::transport::CastTransportSender> transport_sender = + media::cast::transport::CastTransportSender::Create( + NULL, // net log. + clock.get(), + local_endpoint, + remote_endpoint, + logging_config, + base::Bind(&UpdateCastTransportStatus), + base::Bind(&LogRawEvents, cast_environment), + base::TimeDelta::FromSeconds(1), + io_message_loop.message_loop_proxy()); + + transport_sender->InitializeAudio(transport_audio_config); + transport_sender->InitializeVideo(transport_video_config); + scoped_ptr<media::cast::CastSender> cast_sender( media::cast::CastSender::CreateCastSender( cast_environment, @@ -465,7 +491,6 @@ int main(int argc, char** argv) { frame_input)); // Set up event subscribers. - // TODO(imcheng): Set up separate subscribers for audio / video / other. int logging_duration = media::cast::GetLoggingDuration(); scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber; scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber; diff --git a/media/cast/transport/cast_transport.gyp b/media/cast/transport/cast_transport.gyp index 8a69356..9809db3 100644 --- a/media/cast/transport/cast_transport.gyp +++ b/media/cast/transport/cast_transport.gyp @@ -16,6 +16,7 @@ ], 'dependencies': [ '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/media/cast/logging/logging.gyp:cast_common_logging', '<(DEPTH)/net/net.gyp:net', 'utility/utility.gypi:transport_utility', ], diff --git a/media/cast/transport/cast_transport_sender.h b/media/cast/transport/cast_transport_sender.h index 5bfa00e..4f4863b 100644 --- a/media/cast/transport/cast_transport_sender.h +++ b/media/cast/transport/cast_transport_sender.h @@ -29,6 +29,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/non_thread_safe.h" #include "base/time/tick_clock.h" +#include "media/cast/logging/logging_defines.h" #include "media/cast/transport/cast_transport_config.h" #include "media/cast/transport/cast_transport_defines.h" @@ -49,6 +50,9 @@ typedef base::Callback<void(const RtcpSenderInfo& sender_info, base::TimeTicks time_sent, uint32 rtp_timestamp)> CastTransportRtpStatistics; +typedef base::Callback<void(const std::vector<PacketEvent>&)> + BulkRawEventsCallback; + // The application should only trigger this class from the transport thread. class CastTransportSender : public base::NonThreadSafe { public: @@ -57,7 +61,10 @@ class CastTransportSender : public base::NonThreadSafe { base::TickClock* clock, const net::IPEndPoint& local_end_point, const net::IPEndPoint& remote_end_point, + const CastLoggingConfig& logging_config, const CastTransportStatusCallback& status_callback, + const BulkRawEventsCallback& raw_events_callback, + base::TimeDelta raw_events_callback_interval, const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner); virtual ~CastTransportSender() {} diff --git a/media/cast/transport/cast_transport_sender_impl.cc b/media/cast/transport/cast_transport_sender_impl.cc index 9975e3a..38f10f8 100644 --- a/media/cast/transport/cast_transport_sender_impl.cc +++ b/media/cast/transport/cast_transport_sender_impl.cc @@ -17,14 +17,20 @@ scoped_ptr<CastTransportSender> CastTransportSender::Create( base::TickClock* clock, const net::IPEndPoint& local_end_point, const net::IPEndPoint& remote_end_point, + const CastLoggingConfig& logging_config, const CastTransportStatusCallback& status_callback, + const BulkRawEventsCallback& raw_events_callback, + base::TimeDelta raw_events_callback_interval, const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) { return scoped_ptr<CastTransportSender>( new CastTransportSenderImpl(net_log, clock, local_end_point, remote_end_point, + logging_config, status_callback, + raw_events_callback, + raw_events_callback_interval, transport_task_runner.get(), NULL)); } @@ -34,7 +40,10 @@ CastTransportSenderImpl::CastTransportSenderImpl( base::TickClock* clock, const net::IPEndPoint& local_end_point, const net::IPEndPoint& remote_end_point, + const CastLoggingConfig& logging_config, const CastTransportStatusCallback& status_callback, + const BulkRawEventsCallback& raw_events_callback, + base::TimeDelta raw_events_callback_interval, const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner, PacketSender* external_transport) : clock_(clock), @@ -49,9 +58,25 @@ CastTransportSenderImpl::CastTransportSenderImpl( pacer_(clock, external_transport ? external_transport : transport_.get(), transport_task_runner), - rtcp_builder_(&pacer_) {} + rtcp_builder_(&pacer_), + logging_(transport_task_runner, logging_config), + raw_events_callback_(raw_events_callback) { + if (!raw_events_callback_.is_null()) { + DCHECK(logging_config.enable_raw_data_collection); + DCHECK(raw_events_callback_interval > base::TimeDelta()); + event_subscriber_.reset(new SimpleEventSubscriber); + logging_.AddRawEventSubscriber(event_subscriber_.get()); + raw_events_timer_.Start(FROM_HERE, + raw_events_callback_interval, + this, + &CastTransportSenderImpl::SendRawEvents); + } +} -CastTransportSenderImpl::~CastTransportSenderImpl() {} +CastTransportSenderImpl::~CastTransportSenderImpl() { + if (event_subscriber_.get()) + logging_.RemoveRawEventSubscriber(event_subscriber_.get()); +} void CastTransportSenderImpl::InitializeAudio( const CastTransportAudioConfig& config) { @@ -127,6 +152,14 @@ void CastTransportSenderImpl::SubscribeVideoRtpStatsCallback( video_sender_->SubscribeVideoRtpStatsCallback(callback); } +void CastTransportSenderImpl::SendRawEvents() { + DCHECK(event_subscriber_.get()); + DCHECK(!raw_events_callback_.is_null()); + std::vector<PacketEvent> packet_events; + event_subscriber_->GetPacketEventsAndReset(&packet_events); + raw_events_callback_.Run(packet_events); +} + } // namespace transport } // namespace cast } // namespace media diff --git a/media/cast/transport/cast_transport_sender_impl.h b/media/cast/transport/cast_transport_sender_impl.h index b7ee50a..92a665b 100644 --- a/media/cast/transport/cast_transport_sender_impl.h +++ b/media/cast/transport/cast_transport_sender_impl.h @@ -10,6 +10,9 @@ #include "base/memory/scoped_ptr.h" #include "base/time/tick_clock.h" #include "base/time/time.h" +#include "base/timer/timer.h" +#include "media/cast/logging/logging_defines.h" +#include "media/cast/logging/simple_event_subscriber.h" #include "media/cast/transport/cast_transport_config.h" #include "media/cast/transport/cast_transport_sender.h" #include "media/cast/transport/pacing/paced_sender.h" @@ -26,12 +29,20 @@ class CastTransportSenderImpl : public CastTransportSender { // external_transport is only used for testing. // Note that SetPacketReceiver does not work if an external // transport is provided. + // |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. CastTransportSenderImpl( net::NetLog* net_log, base::TickClock* clock, const net::IPEndPoint& local_end_point, const net::IPEndPoint& remote_end_point, + const CastLoggingConfig& logging_config, const CastTransportStatusCallback& status_callback, + const BulkRawEventsCallback& raw_events_callback, + base::TimeDelta raw_events_callback_interval, const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner, PacketSender* external_transport); @@ -71,15 +82,29 @@ class CastTransportSenderImpl : public CastTransportSender { const CastTransportRtpStatistics& callback) OVERRIDE; private: + // If raw events logging is enabled, this is called periodically. + // Calls |raw_events_callback_| with events collected by |event_subscriber_| + // since last call. + void SendRawEvents(); + base::TickClock* clock_; // Not owned by this class. CastTransportStatusCallback status_callback_; scoped_refptr<base::SingleThreadTaskRunner> transport_task_runner_; + scoped_ptr<UdpTransport> transport_; PacedSender pacer_; RtcpBuilder rtcp_builder_; scoped_ptr<TransportAudioSender> audio_sender_; scoped_ptr<TransportVideoSender> video_sender_; + LoggingImpl logging_; + + // This is non-null iff raw events logging is enabled. + scoped_ptr<SimpleEventSubscriber> event_subscriber_; + base::RepeatingTimer<CastTransportSenderImpl> raw_events_timer_; + + BulkRawEventsCallback raw_events_callback_; + DISALLOW_COPY_AND_ASSIGN(CastTransportSenderImpl); }; diff --git a/media/cast/transport/cast_transport_sender_impl_unittest.cc b/media/cast/transport/cast_transport_sender_impl_unittest.cc new file mode 100644 index 0000000..ea6f41c --- /dev/null +++ b/media/cast/transport/cast_transport_sender_impl_unittest.cc @@ -0,0 +1,114 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <gtest/gtest.h> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/test/simple_test_tick_clock.h" +#include "media/cast/cast_config.h" +#include "media/cast/rtcp/rtcp.h" +#include "media/cast/test/fake_single_thread_task_runner.h" +#include "media/cast/transport/cast_transport_config.h" +#include "media/cast/transport/cast_transport_sender_impl.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { +namespace cast { +namespace transport { + +static const int64 kStartMillisecond = GG_INT64_C(12345678900000); + +class FakePacketSender : public transport::PacketSender { + public: + FakePacketSender() {} + + virtual bool SendPacket(const Packet& packet) OVERRIDE { return true; } +}; + +class CastTransportSenderImplTest : public ::testing::Test { + protected: + CastTransportSenderImplTest() + : num_times_callback_called_(0) { + testing_clock_.Advance( + base::TimeDelta::FromMilliseconds(kStartMillisecond)); + task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_); + } + + virtual ~CastTransportSenderImplTest() {} + + void InitWithoutLogging() { + transport_sender_.reset( + new CastTransportSenderImpl(NULL, + &testing_clock_, + net::IPEndPoint(), + net::IPEndPoint(), + GetDefaultCastSenderLoggingConfig(), + base::Bind(&UpdateCastTransportStatus), + BulkRawEventsCallback(), + base::TimeDelta(), + task_runner_, + &transport_)); + task_runner_->RunTasks(); + } + + void InitWithLogging() { + transport_sender_.reset(new CastTransportSenderImpl( + NULL, + &testing_clock_, + net::IPEndPoint(), + net::IPEndPoint(), + GetLoggingConfigWithRawEventsAndStatsEnabled(), + base::Bind(&UpdateCastTransportStatus), + base::Bind(&CastTransportSenderImplTest::LogRawEvents, + base::Unretained(this)), + base::TimeDelta::FromMilliseconds(10), + task_runner_, + &transport_)); + task_runner_->RunTasks(); + } + + void LogRawEvents(const std::vector<PacketEvent>& packet_events) { + num_times_callback_called_++; + if (num_times_callback_called_ == 3) { + run_loop_.Quit(); + } + } + + static void UpdateCastTransportStatus(transport::CastTransportStatus status) { + } + + base::SimpleTestTickClock testing_clock_; + scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; + scoped_ptr<CastTransportSenderImpl> transport_sender_; + FakePacketSender transport_; + base::MessageLoopForIO message_loop_; + base::RunLoop run_loop_; + int num_times_callback_called_; +}; + +TEST_F(CastTransportSenderImplTest, InitWithoutLogging) { + InitWithoutLogging(); + message_loop_.PostDelayedTask(FROM_HERE, + run_loop_.QuitClosure(), + base::TimeDelta::FromMilliseconds(50)); + run_loop_.Run(); + EXPECT_EQ(0, num_times_callback_called_); +} + +TEST_F(CastTransportSenderImplTest, InitWithLogging) { + InitWithLogging(); + message_loop_.PostDelayedTask(FROM_HERE, + run_loop_.QuitClosure(), + base::TimeDelta::FromMilliseconds(50)); + run_loop_.Run(); + EXPECT_GT(num_times_callback_called_, 1); +} + +} // namespace transport +} // namespace cast +} // namespace media diff --git a/media/cast/video_sender/video_sender_unittest.cc b/media/cast/video_sender/video_sender_unittest.cc index 130dac9..982f7de 100644 --- a/media/cast/video_sender/video_sender_unittest.cc +++ b/media/cast/video_sender/video_sender_unittest.cc @@ -81,6 +81,8 @@ class VideoSenderTest : public ::testing::Test { testing_clock_->Advance( base::TimeDelta::FromMilliseconds(kStartMillisecond)); task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_); + CastLoggingConfig logging_config = + GetLoggingConfigWithRawEventsAndStatsEnabled(); cast_environment_ = new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(), task_runner_, @@ -89,7 +91,7 @@ class VideoSenderTest : public ::testing::Test { task_runner_, task_runner_, task_runner_, - GetLoggingConfigWithRawEventsAndStatsEnabled()); + logging_config); transport::CastTransportVideoConfig transport_config; net::IPEndPoint dummy_endpoint; transport_sender_.reset(new transport::CastTransportSenderImpl( @@ -97,7 +99,10 @@ class VideoSenderTest : public ::testing::Test { testing_clock_, dummy_endpoint, dummy_endpoint, + logging_config, base::Bind(&UpdateCastTransportStatus), + transport::BulkRawEventsCallback(), + base::TimeDelta(), task_runner_, &transport_)); transport_sender_->InitializeVideo(transport_config); |