From 23730a6e56a168d1879203e4b3819bb36e3d8f1f Mon Sep 17 00:00:00 2001 From: "Torne (Richard Coles)" Date: Fri, 21 Mar 2014 14:25:57 +0000 Subject: Merge from Chromium at DEPS revision 258528 This commit was generated by merge_to_master.py. Change-Id: Id197cbdde2c2881915f096c0426c741416884783 --- media/cast/audio_receiver/audio_receiver.cc | 2 +- media/cast/audio_receiver/audio_receiver.h | 5 +- media/cast/audio_sender/audio_encoder.cc | 2 +- media/cast/audio_sender/audio_sender.cc | 73 +++--------------- media/cast/audio_sender/audio_sender.h | 12 ++- media/cast/audio_sender/audio_sender_unittest.cc | 1 - media/cast/cast_defines.h | 50 +++++++++++++ media/cast/cast_sender_impl.h | 2 + media/cast/logging/logging_defines.cc | 6 +- media/cast/logging/logging_defines.h | 3 +- media/cast/logging/logging_impl.cc | 31 -------- media/cast/logging/logging_impl_unittest.cc | 1 - media/cast/rtcp/rtcp.cc | 11 +-- media/cast/rtcp/rtcp.h | 13 +--- media/cast/rtcp/rtcp_unittest.cc | 42 +++++------ media/cast/test/end2end_unittest.cc | 1 - media/cast/test/receiver.cc | 4 +- media/cast/test/sender.cc | 6 +- media/cast/test/utility/barcode.cc | 4 +- media/cast/test/utility/default_config.cc | 4 +- media/cast/test/utility/in_process_receiver.h | 2 +- media/cast/transport/cast_transport_sender.h | 1 - media/cast/transport/cast_transport_sender_impl.cc | 7 +- media/cast/transport/cast_transport_sender_impl.h | 1 - .../cast_transport_sender_impl_unittest.cc | 2 - media/cast/transport/pacing/paced_sender.h | 1 + media/cast/transport/rtp_sender/rtp_sender.h | 1 + media/cast/transport/transport/udp_transport.cc | 1 + media/cast/transport/transport/udp_transport.h | 2 + .../cast/video_receiver/codecs/vp8/vp8_decoder.cc | 8 ++ media/cast/video_receiver/video_receiver.cc | 15 +++- media/cast/video_receiver/video_receiver.h | 1 + media/cast/video_sender/external_video_encoder.h | 1 + media/cast/video_sender/video_sender.cc | 87 ++++++++-------------- media/cast/video_sender/video_sender.h | 12 ++- media/cast/video_sender/video_sender_unittest.cc | 9 ++- 36 files changed, 191 insertions(+), 233 deletions(-) (limited to 'media/cast') diff --git a/media/cast/audio_receiver/audio_receiver.cc b/media/cast/audio_receiver/audio_receiver.cc index b5c8e08c14..f7988f55a2 100644 --- a/media/cast/audio_receiver/audio_receiver.cc +++ b/media/cast/audio_receiver/audio_receiver.cc @@ -114,7 +114,7 @@ AudioReceiver::AudioReceiver(scoped_refptr cast_environment, new LocalRtpReceiverStatistics(rtp_receiver_.get())); base::TimeDelta rtcp_interval_delta = base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval); - rtcp_.reset(new Rtcp(cast_environment, NULL, NULL, packet_sender, NULL, + rtcp_.reset(new Rtcp(cast_environment, NULL, NULL, packet_sender, rtp_audio_receiver_statistics_.get(), audio_config.rtcp_mode, rtcp_interval_delta, audio_config.feedback_ssrc, audio_config.incoming_ssrc, diff --git a/media/cast/audio_receiver/audio_receiver.h b/media/cast/audio_receiver/audio_receiver.h index 2742399f33..6270498b6a 100644 --- a/media/cast/audio_receiver/audio_receiver.h +++ b/media/cast/audio_receiver/audio_receiver.h @@ -123,8 +123,6 @@ class AudioReceiver : public base::NonThreadSafe, // Processes raw audio events to be sent over to the cast sender via RTCP. ReceiverRtcpEventSubscriber event_subscriber_; - base::WeakPtrFactory weak_factory_; - const transport::AudioCodec codec_; const int frequency_; base::TimeDelta target_delay_delta_; @@ -148,6 +146,9 @@ class AudioReceiver : public base::NonThreadSafe, // it allows the event to be transmitted via RTCP. RtpTimestamp frame_id_to_rtp_timestamp_[256]; + // NOTE: Weak pointers must be invalidated before all other member variables. + base::WeakPtrFactory weak_factory_; + DISALLOW_COPY_AND_ASSIGN(AudioReceiver); }; diff --git a/media/cast/audio_sender/audio_encoder.cc b/media/cast/audio_sender/audio_encoder.cc index a1b0c95645..ece368f654 100644 --- a/media/cast/audio_sender/audio_encoder.cc +++ b/media/cast/audio_sender/audio_encoder.cc @@ -167,9 +167,9 @@ class AudioEncoder::ImplBase // so far. uint32 rtp_timestamp_; + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; - private: DISALLOW_COPY_AND_ASSIGN(ImplBase); }; diff --git a/media/cast/audio_sender/audio_sender.cc b/media/cast/audio_sender/audio_sender.cc index a02ab2174c..aa1fa6ce4b 100644 --- a/media/cast/audio_sender/audio_sender.cc +++ b/media/cast/audio_sender/audio_sender.cc @@ -35,77 +35,18 @@ class LocalRtcpAudioSenderFeedback : public RtcpSenderFeedback { DISALLOW_IMPLICIT_CONSTRUCTORS(LocalRtcpAudioSenderFeedback); }; -class LocalRtpSenderStatistics : public RtpSenderStatistics { - public: - LocalRtpSenderStatistics( - transport::CastTransportSender* const transport_sender, - int frequency) - : transport_sender_(transport_sender), - frequency_(0), - sender_info_(), - rtp_timestamp_(0), - weak_factory_(this) { - transport_sender_->SubscribeAudioRtpStatsCallback( - base::Bind(&LocalRtpSenderStatistics::StoreStatistics, - weak_factory_.GetWeakPtr())); - } - - virtual void GetStatistics(const base::TimeTicks& now, - transport::RtcpSenderInfo* sender_info) OVERRIDE { - // Update and return last stored statistics. - uint32 ntp_seconds = 0; - uint32 ntp_fraction = 0; - uint32 rtp_timestamp = 0; - if (rtp_timestamp_ > 0) { - base::TimeDelta time_since_last_send = now - time_sent_; - rtp_timestamp = rtp_timestamp_ + time_since_last_send.InMilliseconds() * - (frequency_ / 1000); - // Update NTP time to current time. - ConvertTimeTicksToNtp(now, &ntp_seconds, &ntp_fraction); - } - // Populate sender info. - sender_info->rtp_timestamp = rtp_timestamp; - sender_info->ntp_seconds = sender_info_.ntp_seconds; - sender_info->ntp_fraction = sender_info_.ntp_fraction; - sender_info->send_packet_count = sender_info_.send_packet_count; - sender_info->send_octet_count = sender_info_.send_octet_count; - } - - void StoreStatistics(const transport::RtcpSenderInfo& sender_info, - base::TimeTicks time_sent, - uint32 rtp_timestamp) { - sender_info_ = sender_info; - time_sent_ = time_sent; - rtp_timestamp_ = rtp_timestamp; - } - - private: - transport::CastTransportSender* const transport_sender_; - int frequency_; - transport::RtcpSenderInfo sender_info_; - base::TimeTicks time_sent_; - uint32 rtp_timestamp_; - - base::WeakPtrFactory weak_factory_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(LocalRtpSenderStatistics); -}; - // TODO(mikhal): Reduce heap allocation when not needed. AudioSender::AudioSender(scoped_refptr cast_environment, const AudioSenderConfig& audio_config, transport::CastTransportSender* const transport_sender) : cast_environment_(cast_environment), transport_sender_(transport_sender), + rtp_stats_(audio_config.frequency), rtcp_feedback_(new LocalRtcpAudioSenderFeedback(this)), - rtp_audio_sender_statistics_( - new LocalRtpSenderStatistics(transport_sender_, - audio_config.frequency)), rtcp_(cast_environment, rtcp_feedback_.get(), transport_sender_, NULL, // paced sender. - rtp_audio_sender_statistics_.get(), NULL, audio_config.rtcp_mode, base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval), @@ -124,6 +65,8 @@ AudioSender::AudioSender(scoped_refptr cast_environment, weak_factory_.GetWeakPtr()))); cast_initialization_cb_ = audio_encoder_->InitializationResult(); } + transport_sender_->SubscribeAudioRtpStatsCallback( + base::Bind(&AudioSender::StoreStatistics, weak_factory_.GetWeakPtr())); } AudioSender::~AudioSender() {} @@ -195,12 +138,20 @@ void AudioSender::ScheduleNextRtcpReport() { time_to_next); } +void AudioSender::StoreStatistics( + const transport::RtcpSenderInfo& sender_info, + base::TimeTicks time_sent, + uint32 rtp_timestamp) { + rtp_stats_.Store(sender_info, time_sent, rtp_timestamp); +} + void AudioSender::SendRtcpReport() { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); // We don't send audio logging messages since all captured audio frames will // be sent. transport::RtcpSenderLogMessage empty_msg; - rtcp_.SendRtcpFromRtpSender(empty_msg); + rtp_stats_.UpdateInfo(cast_environment_->Clock()->NowTicks()); + rtcp_.SendRtcpFromRtpSender(empty_msg, rtp_stats_.sender_info()); ScheduleNextRtcpReport(); } diff --git a/media/cast/audio_sender/audio_sender.h b/media/cast/audio_sender/audio_sender.h index 7673b8250f..2acba8a542 100644 --- a/media/cast/audio_sender/audio_sender.h +++ b/media/cast/audio_sender/audio_sender.h @@ -22,7 +22,6 @@ namespace cast { class AudioEncoder; class LocalRtcpAudioSenderFeedback; -class LocalRtpSenderStatistics; // This class is not thread safe. // It's only called from the main cast thread. @@ -63,22 +62,27 @@ class AudioSender : public base::NonThreadSafe, void ResendPacketsOnTransportThread( const transport::MissingFramesAndPacketsMap& missing_packets); + void StoreStatistics(const transport::RtcpSenderInfo& sender_info, + base::TimeTicks time_sent, + uint32 rtp_timestamp); + void ScheduleNextRtcpReport(); void SendRtcpReport(); void InitializeTimers(); - base::WeakPtrFactory weak_factory_; - scoped_refptr cast_environment_; transport::CastTransportSender* const transport_sender_; scoped_ptr audio_encoder_; - scoped_ptr rtp_audio_sender_statistics_; + RtpSenderStatistics rtp_stats_; scoped_ptr rtcp_feedback_; Rtcp rtcp_; bool timers_initialized_; CastInitializationStatus cast_initialization_cb_; + // NOTE: Weak pointers must be invalidated before all other member variables. + base::WeakPtrFactory weak_factory_; + DISALLOW_COPY_AND_ASSIGN(AudioSender); }; diff --git a/media/cast/audio_sender/audio_sender_unittest.cc b/media/cast/audio_sender/audio_sender_unittest.cc index 9b3a52e1d8..49607bacd5 100644 --- a/media/cast/audio_sender/audio_sender_unittest.cc +++ b/media/cast/audio_sender/audio_sender_unittest.cc @@ -80,7 +80,6 @@ class AudioSenderTest : public ::testing::Test { NULL, testing_clock_, dummy_endpoint, - dummy_endpoint, logging_config, base::Bind(&UpdateCastTransportStatus), transport::BulkRawEventsCallback(), diff --git a/media/cast/cast_defines.h b/media/cast/cast_defines.h index 2ee431e827..8826e5d111 100644 --- a/media/cast/cast_defines.h +++ b/media/cast/cast_defines.h @@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "base/time/time.h" +#include "media/cast/transport/cast_transport_config.h" namespace media { namespace cast { @@ -172,6 +173,55 @@ inline uint32 GetVideoRtpTimestamp(const base::TimeTicks& time_ticks) { return static_cast(recorded_delta.InMilliseconds() * 90); } +class RtpSenderStatistics { + public: + explicit RtpSenderStatistics(int frequency) + : frequency_(frequency), + rtp_timestamp_(0) { + memset(&sender_info_, 0, sizeof(sender_info_)); + } + + ~RtpSenderStatistics() {} + + void UpdateInfo(const base::TimeTicks& now) { + // Update RTP timestamp and return last stored statistics. + uint32 ntp_seconds = 0; + uint32 ntp_fraction = 0; + uint32 rtp_timestamp = 0; + if (rtp_timestamp_ > 0) { + base::TimeDelta time_since_last_send = now - time_sent_; + rtp_timestamp = rtp_timestamp_ + time_since_last_send.InMilliseconds() * + (frequency_ / 1000); + // Update NTP time to current time. + ConvertTimeTicksToNtp(now, &ntp_seconds, &ntp_fraction); + } + // Populate sender info. + sender_info_.rtp_timestamp = rtp_timestamp; + sender_info_.ntp_seconds = ntp_seconds; + sender_info_.ntp_fraction = ntp_fraction; + } + + transport::RtcpSenderInfo sender_info() const { + return sender_info_; + } + + void Store(transport::RtcpSenderInfo sender_info, + base::TimeTicks time_sent, + uint32 rtp_timestamp) { + sender_info_ = sender_info; + time_sent_ = time_sent; + rtp_timestamp_ = rtp_timestamp; +} + + private: + int frequency_; + transport::RtcpSenderInfo sender_info_; + base::TimeTicks time_sent_; + uint32 rtp_timestamp_; + + DISALLOW_COPY_AND_ASSIGN(RtpSenderStatistics); +}; + } // namespace cast } // namespace media diff --git a/media/cast/cast_sender_impl.h b/media/cast/cast_sender_impl.h index 85b8669192..b90bec4e1b 100644 --- a/media/cast/cast_sender_impl.h +++ b/media/cast/cast_sender_impl.h @@ -57,6 +57,8 @@ class CastSenderImpl : public CastSender { transport::CastTransportSender* const transport_sender_; uint32 ssrc_of_audio_sender_; uint32 ssrc_of_video_sender_; + + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(CastSenderImpl); diff --git a/media/cast/logging/logging_defines.cc b/media/cast/logging/logging_defines.cc index 5a695ce20a..adb1f040cf 100644 --- a/media/cast/logging/logging_defines.cc +++ b/media/cast/logging/logging_defines.cc @@ -15,8 +15,7 @@ namespace cast { CastLoggingConfig::CastLoggingConfig() : enable_raw_data_collection(false), - enable_stats_data_collection(false), - enable_tracing(false) {} + enable_stats_data_collection(false) {} CastLoggingConfig::~CastLoggingConfig() {} @@ -35,7 +34,7 @@ CastLoggingConfig GetLoggingConfigWithRawEventsAndStatsEnabled() { return config; } -std::string CastLoggingToString(CastLoggingEvent event) { +const char* CastLoggingToString(CastLoggingEvent event) { switch (event) { // Can happen if the sender and receiver of RTCP log messages are not // aligned. @@ -147,4 +146,3 @@ GenericLogStats::GenericLogStats() GenericLogStats::~GenericLogStats() {} } // namespace cast } // namespace media - diff --git a/media/cast/logging/logging_defines.h b/media/cast/logging/logging_defines.h index f9c6d8b237..b4e18145f8 100644 --- a/media/cast/logging/logging_defines.h +++ b/media/cast/logging/logging_defines.h @@ -25,7 +25,6 @@ struct CastLoggingConfig { bool enable_raw_data_collection; bool enable_stats_data_collection; - bool enable_tracing; }; // Currently these are the same as the default config. @@ -77,7 +76,7 @@ enum CastLoggingEvent { kNumOfLoggingEvents = kDuplicateVideoPacketReceived }; -std::string CastLoggingToString(CastLoggingEvent event); +const char* CastLoggingToString(CastLoggingEvent event); // CastLoggingEvent are classified into one of three following types. enum EventMediaType { AUDIO_EVENT, VIDEO_EVENT, OTHER_EVENT }; diff --git a/media/cast/logging/logging_impl.cc b/media/cast/logging/logging_impl.cc index 14ee744c00..0f07a5adc2 100644 --- a/media/cast/logging/logging_impl.cc +++ b/media/cast/logging/logging_impl.cc @@ -28,11 +28,6 @@ void LoggingImpl::InsertFrameEvent(const base::TimeTicks& time_of_event, if (config_.enable_stats_data_collection) { stats_.InsertFrameEvent(time_of_event, event, rtp_timestamp, frame_id); } - if (config_.enable_tracing) { - std::string event_string = CastLoggingToString(event); - TRACE_EVENT_INSTANT2(event_string.c_str(), "FE", TRACE_EVENT_SCOPE_THREAD, - "rtp_timestamp", rtp_timestamp, "frame_id", frame_id); - } } void LoggingImpl::InsertFrameEventWithSize(const base::TimeTicks& time_of_event, @@ -48,13 +43,6 @@ void LoggingImpl::InsertFrameEventWithSize(const base::TimeTicks& time_of_event, stats_.InsertFrameEventWithSize(time_of_event, event, rtp_timestamp, frame_id, frame_size); } - - if (config_.enable_tracing) { - std::string event_string = CastLoggingToString(event); - TRACE_EVENT_INSTANT2(event_string.c_str(), "FES", TRACE_EVENT_SCOPE_THREAD, - "rtp_timestamp", rtp_timestamp, "frame_size", - frame_size); - } } void LoggingImpl::InsertFrameEventWithDelay( @@ -69,13 +57,6 @@ void LoggingImpl::InsertFrameEventWithDelay( stats_.InsertFrameEventWithDelay(time_of_event, event, rtp_timestamp, frame_id, delay); } - - if (config_.enable_tracing) { - std::string event_string = CastLoggingToString(event); - TRACE_EVENT_INSTANT2(event_string.c_str(), "FED", TRACE_EVENT_SCOPE_THREAD, - "rtp_timestamp", rtp_timestamp, "delay", - delay.InMilliseconds()); - } } void LoggingImpl::InsertSinglePacketEvent(const base::TimeTicks& time_of_event, @@ -129,12 +110,6 @@ void LoggingImpl::InsertPacketEvent(const base::TimeTicks& time_of_event, stats_.InsertPacketEvent(time_of_event, event, rtp_timestamp, frame_id, packet_id, max_packet_id, size); } - if (config_.enable_tracing) { - std::string event_string = CastLoggingToString(event); - TRACE_EVENT_INSTANT2(event_string.c_str(), "PE", TRACE_EVENT_SCOPE_THREAD, - "rtp_timestamp", rtp_timestamp, "packet_id", - packet_id); - } } void LoggingImpl::InsertGenericEvent(const base::TimeTicks& time_of_event, @@ -146,12 +121,6 @@ void LoggingImpl::InsertGenericEvent(const base::TimeTicks& time_of_event, if (config_.enable_stats_data_collection) { stats_.InsertGenericEvent(time_of_event, event, value); } - - if (config_.enable_tracing) { - std::string event_string = CastLoggingToString(event); - TRACE_EVENT_INSTANT1(event_string.c_str(), "GE", TRACE_EVENT_SCOPE_THREAD, - "value", value); - } } void LoggingImpl::AddRawEventSubscriber(RawEventSubscriber* subscriber) { diff --git a/media/cast/logging/logging_impl_unittest.cc b/media/cast/logging/logging_impl_unittest.cc index 92da7c14da..39bf91db92 100644 --- a/media/cast/logging/logging_impl_unittest.cc +++ b/media/cast/logging/logging_impl_unittest.cc @@ -29,7 +29,6 @@ class LoggingImplTest : public ::testing::Test { // Enable all logging types. config_.enable_raw_data_collection = true; config_.enable_stats_data_collection = true; - config_.enable_tracing = true; testing_clock_.Advance( base::TimeDelta::FromMilliseconds(kStartMillisecond)); diff --git a/media/cast/rtcp/rtcp.cc b/media/cast/rtcp/rtcp.cc index 9f2007a2fb..c56d093284 100644 --- a/media/cast/rtcp/rtcp.cc +++ b/media/cast/rtcp/rtcp.cc @@ -158,7 +158,6 @@ Rtcp::Rtcp(scoped_refptr cast_environment, RtcpSenderFeedback* sender_feedback, transport::CastTransportSender* const transport_sender, transport::PacedPacketSender* paced_packet_sender, - RtpSenderStatistics* rtp_sender_statistics, RtpReceiverStatistics* rtp_receiver_statistics, RtcpMode rtcp_mode, const base::TimeDelta& rtcp_interval, uint32 local_ssrc, uint32 remote_ssrc, const std::string& c_name) @@ -169,7 +168,6 @@ Rtcp::Rtcp(scoped_refptr cast_environment, local_ssrc_(local_ssrc), remote_ssrc_(remote_ssrc), c_name_(c_name), - rtp_sender_statistics_(rtp_sender_statistics), rtp_receiver_statistics_(rtp_receiver_statistics), receiver_feedback_(new LocalRtcpReceiverFeedback(this, cast_environment)), rtt_feedback_(new LocalRtcpRttFeedback(this)), @@ -287,7 +285,8 @@ void Rtcp::SendRtcpFromRtpReceiver( } void Rtcp::SendRtcpFromRtpSender( - const transport::RtcpSenderLogMessage& sender_log_message) { + const transport::RtcpSenderLogMessage& sender_log_message, + transport::RtcpSenderInfo sender_info) { DCHECK(transport_sender_); uint32 packet_type_flags = transport::kRtcpSr; base::TimeTicks now = cast_environment_->Clock()->NowTicks(); @@ -296,12 +295,6 @@ void Rtcp::SendRtcpFromRtpSender( packet_type_flags |= transport::kRtcpSenderLog; } - transport::RtcpSenderInfo sender_info; - if (rtp_sender_statistics_) { - rtp_sender_statistics_->GetStatistics(now, &sender_info); - } else { - memset(&sender_info, 0, sizeof(sender_info)); - } SaveLastSentNtpTime(now, sender_info.ntp_seconds, sender_info.ntp_fraction); transport::RtcpDlrrReportBlock dlrr; diff --git a/media/cast/rtcp/rtcp.h b/media/cast/rtcp/rtcp.h index 59ba3d99f9..8759f6bf4f 100644 --- a/media/cast/rtcp/rtcp.h +++ b/media/cast/rtcp/rtcp.h @@ -44,14 +44,6 @@ class RtcpSenderFeedback { virtual ~RtcpSenderFeedback() {} }; -class RtpSenderStatistics { - public: - virtual void GetStatistics(const base::TimeTicks& now, - transport::RtcpSenderInfo* sender_info) = 0; - - virtual ~RtpSenderStatistics() {} -}; - class RtpReceiverStatistics { public: virtual void GetStatistics(uint8* fraction_lost, @@ -71,7 +63,6 @@ class Rtcp { RtcpSenderFeedback* sender_feedback, transport::CastTransportSender* const transport_sender, // Send-side. transport::PacedPacketSender* paced_packet_sender, // Receive side. - RtpSenderStatistics* rtp_sender_statistics, RtpReceiverStatistics* rtp_receiver_statistics, RtcpMode rtcp_mode, const base::TimeDelta& rtcp_interval, @@ -93,7 +84,8 @@ class Rtcp { // not fit in the packet the |sender_log_message| will contain the remaining // unsent messages. void SendRtcpFromRtpSender( - const transport::RtcpSenderLogMessage& sender_log_message); + const transport::RtcpSenderLogMessage& sender_log_message, + transport::RtcpSenderInfo sender_info); // |cast_message| and |event_subscriber| is optional; if |cast_message| is // provided the RTCP receiver report will append a Cast message containing @@ -169,7 +161,6 @@ class Rtcp { const std::string c_name_; // Not owned by this class. - RtpSenderStatistics* const rtp_sender_statistics_; RtpReceiverStatistics* const rtp_receiver_statistics_; scoped_ptr rtt_feedback_; diff --git a/media/cast/rtcp/rtcp_unittest.cc b/media/cast/rtcp/rtcp_unittest.cc index ac7144c710..bcf7be11ac 100644 --- a/media/cast/rtcp/rtcp_unittest.cc +++ b/media/cast/rtcp/rtcp_unittest.cc @@ -117,7 +117,6 @@ class RtcpPeer : public Rtcp { RtcpSenderFeedback* sender_feedback, transport::CastTransportSender* const transport_sender, transport::PacedPacketSender* paced_packet_sender, - RtpSenderStatistics* rtp_sender_statistics, RtpReceiverStatistics* rtp_receiver_statistics, RtcpMode rtcp_mode, const base::TimeDelta& rtcp_interval, @@ -128,7 +127,6 @@ class RtcpPeer : public Rtcp { sender_feedback, transport_sender, paced_packet_sender, - rtp_sender_statistics, rtp_receiver_statistics, rtcp_mode, rtcp_interval, @@ -156,7 +154,8 @@ class RtcpTest : public ::testing::Test { task_runner_, logging_config_)), sender_to_receiver_(testing_clock_), - receiver_to_sender_(cast_environment_, testing_clock_) { + receiver_to_sender_(cast_environment_, testing_clock_), + rtp_sender_stats_(kVideoFrequency) { testing_clock_->Advance( base::TimeDelta::FromMilliseconds(kStartMillisecond)); net::IPEndPoint dummy_endpoint; @@ -164,7 +163,6 @@ class RtcpTest : public ::testing::Test { NULL, testing_clock_, dummy_endpoint, - dummy_endpoint, logging_config_, base::Bind(&UpdateCastTransportStatus), transport::BulkRawEventsCallback(), @@ -198,6 +196,7 @@ class RtcpTest : public ::testing::Test { scoped_ptr transport_sender_; LocalRtcpTransport receiver_to_sender_; MockRtcpSenderFeedback mock_sender_feedback_; + RtpSenderStatistics rtp_sender_stats_; DISALLOW_COPY_AND_ASSIGN(RtcpTest); }; @@ -210,7 +209,6 @@ TEST_F(RtcpTest, TimeToSend) { transport_sender_.get(), &receiver_to_sender_, NULL, - NULL, kRtcpCompound, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, @@ -232,7 +230,6 @@ TEST_F(RtcpTest, BasicSenderReport) { transport_sender_.get(), NULL, NULL, - NULL, kRtcpCompound, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, @@ -240,7 +237,7 @@ TEST_F(RtcpTest, BasicSenderReport) { kCName); sender_to_receiver_.set_rtcp_receiver(&rtcp); transport::RtcpSenderLogMessage empty_sender_log; - rtcp.SendRtcpFromRtpSender(empty_sender_log); + rtcp.SendRtcpFromRtpSender(empty_sender_log, rtp_sender_stats_.sender_info()); } TEST_F(RtcpTest, BasicReceiverReport) { @@ -249,7 +246,6 @@ TEST_F(RtcpTest, BasicReceiverReport) { NULL, &receiver_to_sender_, NULL, - NULL, kRtcpCompound, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, @@ -268,7 +264,6 @@ TEST_F(RtcpTest, BasicCast) { NULL, &receiver_to_sender_, NULL, - NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, @@ -295,7 +290,6 @@ TEST_F(RtcpTest, RttReducedSizeRtcp) { NULL, &receiver_to_sender_, NULL, - NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kReceiverSsrc, @@ -308,7 +302,6 @@ TEST_F(RtcpTest, RttReducedSizeRtcp) { transport_sender_.get(), NULL, NULL, - NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, @@ -326,7 +319,8 @@ TEST_F(RtcpTest, RttReducedSizeRtcp) { EXPECT_FALSE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); transport::RtcpSenderLogMessage empty_sender_log; - rtcp_sender.SendRtcpFromRtpSender(empty_sender_log); + rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, + rtp_sender_stats_.sender_info()); RunTasks(33); rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); @@ -335,7 +329,8 @@ TEST_F(RtcpTest, RttReducedSizeRtcp) { EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); - rtcp_sender.SendRtcpFromRtpSender(empty_sender_log); + rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, + rtp_sender_stats_.sender_info()); RunTasks(33); EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); @@ -352,7 +347,6 @@ TEST_F(RtcpTest, Rtt) { NULL, &receiver_to_sender_, NULL, - NULL, kRtcpCompound, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kReceiverSsrc, @@ -365,7 +359,6 @@ TEST_F(RtcpTest, Rtt) { transport_sender_.get(), NULL, NULL, - NULL, kRtcpCompound, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, @@ -383,7 +376,8 @@ TEST_F(RtcpTest, Rtt) { EXPECT_FALSE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); transport::RtcpSenderLogMessage empty_sender_log; - rtcp_sender.SendRtcpFromRtpSender(empty_sender_log); + rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, + rtp_sender_stats_.sender_info()); RunTasks(33); rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); @@ -398,7 +392,8 @@ TEST_F(RtcpTest, Rtt) { EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); - rtcp_sender.SendRtcpFromRtpSender(empty_sender_log); + rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, + rtp_sender_stats_.sender_info()); RunTasks(33); EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 2); @@ -416,7 +411,8 @@ TEST_F(RtcpTest, Rtt) { EXPECT_NEAR(kAddedDelay + kAddedShortDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); - rtcp_sender.SendRtcpFromRtpSender(empty_sender_log); + rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, + rtp_sender_stats_.sender_info()); RunTasks(33); EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(2 * kAddedShortDelay, rtt.InMilliseconds(), 1); @@ -446,7 +442,6 @@ TEST_F(RtcpTest, RttWithPacketLoss) { NULL, &receiver_to_sender_, NULL, - NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, @@ -459,7 +454,6 @@ TEST_F(RtcpTest, RttWithPacketLoss) { transport_sender_.get(), NULL, NULL, - NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kReceiverSsrc, @@ -471,7 +465,8 @@ TEST_F(RtcpTest, RttWithPacketLoss) { rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); transport::RtcpSenderLogMessage empty_sender_log; - rtcp_sender.SendRtcpFromRtpSender(empty_sender_log); + rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, + rtp_sender_stats_.sender_info()); RunTasks(33); base::TimeDelta rtt; @@ -490,7 +485,8 @@ TEST_F(RtcpTest, RttWithPacketLoss) { receiver_to_sender_.set_drop_packets(true); rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); - rtcp_sender.SendRtcpFromRtpSender(empty_sender_log); + rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, + rtp_sender_stats_.sender_info()); RunTasks(33); EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); @@ -549,7 +545,6 @@ TEST_F(RtcpTest, WrapAround) { transport_sender_.get(), NULL, NULL, - NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kReceiverSsrc, @@ -578,7 +573,6 @@ TEST_F(RtcpTest, RtpTimestampInSenderTime) { transport_sender_.get(), &receiver_to_sender_, NULL, - NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kReceiverSsrc, diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc index 4c9fa2aaac..e85f9aa716 100644 --- a/media/cast/test/end2end_unittest.cc +++ b/media/cast/test/end2end_unittest.cc @@ -505,7 +505,6 @@ class End2EndTest : public ::testing::Test { NULL, testing_clock_sender_, dummy_endpoint, - dummy_endpoint, logging_config_, base::Bind(&UpdateCastTransportStatus), base::Bind(&End2EndTest::LogRawEvents, base::Unretained(this)), diff --git a/media/cast/test/receiver.cc b/media/cast/test/receiver.cc index 22abe7c6d7..052d02d46c 100644 --- a/media/cast/test/receiver.cc +++ b/media/cast/test/receiver.cc @@ -40,8 +40,8 @@ namespace cast { #define DEFAULT_RECEIVE_PORT "2344" #define DEFAULT_SEND_IP "0.0.0.0" #define DEFAULT_RESTART "0" -#define DEFAULT_AUDIO_FEEDBACK_SSRC "1" -#define DEFAULT_AUDIO_INCOMING_SSRC "2" +#define DEFAULT_AUDIO_FEEDBACK_SSRC "2" +#define DEFAULT_AUDIO_INCOMING_SSRC "1" #define DEFAULT_AUDIO_PAYLOAD_TYPE "127" #define DEFAULT_VIDEO_FEEDBACK_SSRC "12" #define DEFAULT_VIDEO_INCOMING_SSRC "11" diff --git a/media/cast/test/sender.cc b/media/cast/test/sender.cc index 10e48e8f5c..62c6bf3f3d 100644 --- a/media/cast/test/sender.cc +++ b/media/cast/test/sender.cc @@ -326,7 +326,11 @@ class SendProcess { base::TimeTicks start_time_; base::TimeTicks send_time_; scoped_ptr audio_bus_factory_; + + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(SendProcess); }; } // namespace cast @@ -458,7 +462,6 @@ int main(int argc, char** argv) { media::cast::transport::CastTransportVideoConfig transport_video_config; net::IPEndPoint remote_endpoint = CreateUDPAddress(remote_ip_address, remote_port); - net::IPEndPoint local_endpoint = CreateUDPAddress("0.0.0.0", 0); transport_audio_config.base.ssrc = audio_config.sender_ssrc; transport_audio_config.base.rtp_config = audio_config.rtp_config; transport_video_config.base.ssrc = video_config.sender_ssrc; @@ -481,7 +484,6 @@ int main(int argc, char** argv) { media::cast::transport::CastTransportSender::Create( NULL, // net log. cast_environment->Clock(), - local_endpoint, remote_endpoint, logging_config, base::Bind(&UpdateCastTransportStatus), diff --git a/media/cast/test/utility/barcode.cc b/media/cast/test/utility/barcode.cc index 9aadd23031..fbb17f18e8 100644 --- a/media/cast/test/utility/barcode.cc +++ b/media/cast/test/utility/barcode.cc @@ -32,8 +32,8 @@ namespace media { namespace cast { namespace test { -const int kBlackThreshold = 256 / 3; -const int kWhiteThreshold = 256 * 2 / 3; +const int kBlackThreshold = 256 * 2 / 3; +const int kWhiteThreshold = 256 / 3; bool EncodeBarcode(const std::vector& bits, scoped_refptr output_frame) { diff --git a/media/cast/test/utility/default_config.cc b/media/cast/test/utility/default_config.cc index 350bd517c4..34eaedc3de 100644 --- a/media/cast/test/utility/default_config.cc +++ b/media/cast/test/utility/default_config.cc @@ -11,8 +11,8 @@ namespace cast { AudioReceiverConfig GetDefaultAudioReceiverConfig() { AudioReceiverConfig config; - config.feedback_ssrc = 1; - config.incoming_ssrc = 2; + config.feedback_ssrc = 2; + config.incoming_ssrc = 1; config.rtp_payload_type = 127; config.rtcp_c_name = "audio_receiver@a.b.c.d"; config.use_external_decoder = false; diff --git a/media/cast/test/utility/in_process_receiver.h b/media/cast/test/utility/in_process_receiver.h index 57d8a86314..a5b13cee43 100644 --- a/media/cast/test/utility/in_process_receiver.h +++ b/media/cast/test/utility/in_process_receiver.h @@ -101,7 +101,7 @@ class InProcessReceiver { scoped_ptr transport_; scoped_ptr cast_receiver_; - // For shutdown safety, this member must be last: + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(InProcessReceiver); diff --git a/media/cast/transport/cast_transport_sender.h b/media/cast/transport/cast_transport_sender.h index 4f4863b95d..dda12cce7f 100644 --- a/media/cast/transport/cast_transport_sender.h +++ b/media/cast/transport/cast_transport_sender.h @@ -59,7 +59,6 @@ class CastTransportSender : public base::NonThreadSafe { static scoped_ptr Create( 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, diff --git a/media/cast/transport/cast_transport_sender_impl.cc b/media/cast/transport/cast_transport_sender_impl.cc index 46dfaaf2d2..1157fff297 100644 --- a/media/cast/transport/cast_transport_sender_impl.cc +++ b/media/cast/transport/cast_transport_sender_impl.cc @@ -15,7 +15,6 @@ namespace transport { scoped_ptr CastTransportSender::Create( 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, @@ -25,7 +24,6 @@ scoped_ptr CastTransportSender::Create( return scoped_ptr( new CastTransportSenderImpl(net_log, clock, - local_end_point, remote_end_point, logging_config, status_callback, @@ -38,7 +36,6 @@ scoped_ptr CastTransportSender::Create( CastTransportSenderImpl::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, @@ -52,7 +49,7 @@ CastTransportSenderImpl::CastTransportSenderImpl( transport_(external_transport ? NULL : new UdpTransport(net_log, transport_task_runner, - local_end_point, + net::IPEndPoint(), remote_end_point, status_callback)), logging_(logging_config), @@ -151,7 +148,7 @@ void CastTransportSenderImpl::SubscribeAudioRtpStatsCallback( void CastTransportSenderImpl::SubscribeVideoRtpStatsCallback( const CastTransportRtpStatistics& callback) { - DCHECK(video_sender_) << "Audio sender uninitialized"; + DCHECK(video_sender_) << "Video sender uninitialized"; video_sender_->SubscribeVideoRtpStatsCallback(callback); } diff --git a/media/cast/transport/cast_transport_sender_impl.h b/media/cast/transport/cast_transport_sender_impl.h index 765de12fe3..c8ead5e023 100644 --- a/media/cast/transport/cast_transport_sender_impl.h +++ b/media/cast/transport/cast_transport_sender_impl.h @@ -37,7 +37,6 @@ class CastTransportSenderImpl : public CastTransportSender { 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, diff --git a/media/cast/transport/cast_transport_sender_impl_unittest.cc b/media/cast/transport/cast_transport_sender_impl_unittest.cc index ea6f41c86f..34ebf80223 100644 --- a/media/cast/transport/cast_transport_sender_impl_unittest.cc +++ b/media/cast/transport/cast_transport_sender_impl_unittest.cc @@ -46,7 +46,6 @@ class CastTransportSenderImplTest : public ::testing::Test { new CastTransportSenderImpl(NULL, &testing_clock_, net::IPEndPoint(), - net::IPEndPoint(), GetDefaultCastSenderLoggingConfig(), base::Bind(&UpdateCastTransportStatus), BulkRawEventsCallback(), @@ -61,7 +60,6 @@ class CastTransportSenderImplTest : public ::testing::Test { NULL, &testing_clock_, net::IPEndPoint(), - net::IPEndPoint(), GetLoggingConfigWithRawEventsAndStatsEnabled(), base::Bind(&UpdateCastTransportStatus), base::Bind(&CastTransportSenderImplTest::LogRawEvents, diff --git a/media/cast/transport/pacing/paced_sender.h b/media/cast/transport/pacing/paced_sender.h index 36deb029c8..7140cab580 100644 --- a/media/cast/transport/pacing/paced_sender.h +++ b/media/cast/transport/pacing/paced_sender.h @@ -98,6 +98,7 @@ class PacedSender : public PacedPacketSender, PacketList packet_list_; PacketList resend_packet_list_; + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(PacedSender); diff --git a/media/cast/transport/rtp_sender/rtp_sender.h b/media/cast/transport/rtp_sender/rtp_sender.h index 072affbecb..761ed16427 100644 --- a/media/cast/transport/rtp_sender/rtp_sender.h +++ b/media/cast/transport/rtp_sender/rtp_sender.h @@ -80,6 +80,7 @@ class RtpSender { CastTransportRtpStatistics stats_callback_; scoped_refptr transport_task_runner_; + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(RtpSender); diff --git a/media/cast/transport/transport/udp_transport.cc b/media/cast/transport/transport/udp_transport.cc index faea49851d..1246451dd0 100644 --- a/media/cast/transport/transport/udp_transport.cc +++ b/media/cast/transport/transport/udp_transport.cc @@ -121,6 +121,7 @@ void UdpTransport::ReceiveNextPacket(int length_or_status) { // ignore it. If this is the first packet being received and no remote // address has been set, set the remote address and expect all future // packets to come from the same one. + // TODO(hubbe): We should only do this if the caller used a valid ssrc. if (IsEmpty(remote_addr_)) { remote_addr_ = recv_addr_; VLOG(1) << "Setting remote address from first received packet: " diff --git a/media/cast/transport/transport/udp_transport.h b/media/cast/transport/transport/udp_transport.h index d316416dd2..15f5839fab 100644 --- a/media/cast/transport/transport/udp_transport.h +++ b/media/cast/transport/transport/udp_transport.h @@ -69,6 +69,8 @@ class UdpTransport : public PacketSender { net::IPEndPoint recv_addr_; PacketReceiverCallback packet_receiver_; const CastTransportStatusCallback status_callback_; + + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(UdpTransport); diff --git a/media/cast/video_receiver/codecs/vp8/vp8_decoder.cc b/media/cast/video_receiver/codecs/vp8/vp8_decoder.cc index b5304bd15e..02b94b37fa 100644 --- a/media/cast/video_receiver/codecs/vp8/vp8_decoder.cc +++ b/media/cast/video_receiver/codecs/vp8/vp8_decoder.cc @@ -5,6 +5,7 @@ #include "media/cast/video_receiver/codecs/vp8/vp8_decoder.h" #include "base/bind.h" +#include "base/debug/trace_event.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "media/base/video_frame.h" @@ -126,6 +127,13 @@ bool Vp8Decoder::Decode(const transport::EncodedVideoFrame* encoded_frame, cast_environment_, encoded_frame->rtp_timestamp, encoded_frame->frame_id)); + + // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc + TRACE_EVENT_INSTANT1( + "cast_perf_test", "FrameDecoded", + TRACE_EVENT_SCOPE_THREAD, + "rtp_timestamp", encoded_frame->rtp_timestamp); + // Frame decoded - return frame to the user via callback. cast_environment_->PostTask( CastEnvironment::MAIN, diff --git a/media/cast/video_receiver/video_receiver.cc b/media/cast/video_receiver/video_receiver.cc index 81f22aae4d..5855218178 100644 --- a/media/cast/video_receiver/video_receiver.cc +++ b/media/cast/video_receiver/video_receiver.cc @@ -7,6 +7,7 @@ #include #include "base/bind.h" +#include "base/debug/trace_event.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "media/cast/cast_defines.h" @@ -134,7 +135,6 @@ VideoReceiver::VideoReceiver(scoped_refptr cast_environment, NULL, NULL, packet_sender, - NULL, rtp_video_receiver_statistics_.get(), video_config.rtcp_mode, base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), @@ -170,6 +170,7 @@ void VideoReceiver::DecodeVideoFrame( scoped_ptr encoded_frame, const base::TimeTicks& render_time) { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); + // Hand the ownership of the encoded frame to the decode thread. cast_environment_->PostTask(CastEnvironment::VIDEO_DECODER, FROM_HERE, @@ -310,6 +311,14 @@ bool VideoReceiver::PullEncodedVideoFrame( // We have a copy of the frame, release this one. framer_->ReleaseFrame((*encoded_frame)->frame_id); (*encoded_frame)->codec = codec_; + + // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc + TRACE_EVENT_INSTANT2( + "cast_perf_test", "PullEncodedVideoFrame", + TRACE_EVENT_SCOPE_THREAD, + "rtp_timestamp", (*encoded_frame)->rtp_timestamp, + "render_time", render_time->ToInternalValue()); + return true; } @@ -364,8 +373,8 @@ base::TimeTicks VideoReceiver::GetRenderTime(base::TimeTicks now, if (time_offset_counter_ == 0) { // Check for received RTCP to sync the stream play it out asap. if (rtcp_->RtpTimestampInSenderTime(kVideoFrequency, - incoming_rtp_timestamp_, - &rtp_timestamp_in_ticks)) { + incoming_rtp_timestamp_, + &rtp_timestamp_in_ticks)) { ++time_offset_counter_; } diff --git a/media/cast/video_receiver/video_receiver.h b/media/cast/video_receiver/video_receiver.h index ce9f9eb7ef..839f131386 100644 --- a/media/cast/video_receiver/video_receiver.h +++ b/media/cast/video_receiver/video_receiver.h @@ -137,6 +137,7 @@ class VideoReceiver : public base::NonThreadSafe, // it allows the event to be transmitted via RTCP. RtpTimestamp frame_id_to_rtp_timestamp_[256]; + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(VideoReceiver); diff --git a/media/cast/video_sender/external_video_encoder.h b/media/cast/video_sender/external_video_encoder.h index 446cac5a4d..6c4c97e922 100644 --- a/media/cast/video_sender/external_video_encoder.h +++ b/media/cast/video_sender/external_video_encoder.h @@ -71,6 +71,7 @@ class ExternalVideoEncoder : public VideoEncoder { // Weak pointer factory for posting back LocalVideoEncodeAcceleratorClient // notifications to ExternalVideoEncoder. + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(ExternalVideoEncoder); diff --git a/media/cast/video_sender/video_sender.cc b/media/cast/video_sender/video_sender.cc index 6f6c649022..f3955277dd 100644 --- a/media/cast/video_sender/video_sender.cc +++ b/media/cast/video_sender/video_sender.cc @@ -8,6 +8,7 @@ #include #include "base/bind.h" +#include "base/debug/trace_event.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "media/cast/cast_defines.h" @@ -43,54 +44,6 @@ class LocalRtcpVideoSenderFeedback : public RtcpSenderFeedback { DISALLOW_IMPLICIT_CONSTRUCTORS(LocalRtcpVideoSenderFeedback); }; -class LocalRtpVideoSenderStatistics : public RtpSenderStatistics { - public: - explicit LocalRtpVideoSenderStatistics( - transport::CastTransportSender* const transport_sender) - : transport_sender_(transport_sender), sender_info_(), rtp_timestamp_(0) { - transport_sender_->SubscribeVideoRtpStatsCallback( - base::Bind(&LocalRtpVideoSenderStatistics::StoreStatistics, - base::Unretained(this))); - } - - virtual void GetStatistics(const base::TimeTicks& now, - transport::RtcpSenderInfo* sender_info) OVERRIDE { - // Update RTP timestamp and return last stored statistics. - uint32 ntp_seconds = 0; - uint32 ntp_fraction = 0; - uint32 rtp_timestamp = 0; - if (rtp_timestamp_ > 0) { - base::TimeDelta time_since_last_send = now - time_sent_; - rtp_timestamp = rtp_timestamp_ + time_since_last_send.InMilliseconds() * - (kVideoFrequency / 1000); - // Update NTP time to current time. - ConvertTimeTicksToNtp(now, &ntp_seconds, &ntp_fraction); - } - // Populate sender info. - sender_info->rtp_timestamp = rtp_timestamp; - sender_info->ntp_seconds = ntp_seconds; - sender_info->ntp_fraction = ntp_fraction; - sender_info->send_packet_count = sender_info_.send_packet_count; - sender_info->send_octet_count = sender_info_.send_octet_count; - } - - void StoreStatistics(const transport::RtcpSenderInfo& sender_info, - base::TimeTicks time_sent, - uint32 rtp_timestamp) { - sender_info_ = sender_info; - time_sent_ = time_sent; - rtp_timestamp_ = rtp_timestamp; - } - - private: - transport::CastTransportSender* const transport_sender_; - transport::RtcpSenderInfo sender_info_; - base::TimeTicks time_sent_; - uint32 rtp_timestamp_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(LocalRtpVideoSenderStatistics); -}; - VideoSender::VideoSender( scoped_refptr cast_environment, const VideoSenderConfig& video_config, @@ -103,6 +56,7 @@ VideoSender::VideoSender( cast_environment_(cast_environment), transport_sender_(transport_sender), event_subscriber_(kMaxEventSubscriberEntries), + rtp_stats_(kVideoFrequency), rtcp_feedback_(new LocalRtcpVideoSenderFeedback(this)), last_acked_frame_id_(-1), last_sent_frame_id_(-1), @@ -122,9 +76,6 @@ VideoSender::VideoSender( VLOG(1) << "max_unacked_frames " << static_cast(max_unacked_frames_); DCHECK_GT(max_unacked_frames_, 0) << "Invalid argument"; - rtp_video_sender_statistics_.reset( - new LocalRtpVideoSenderStatistics(transport_sender)); - if (video_config.use_external_encoder) { CHECK(gpu_factories); video_encoder_.reset(new ExternalVideoEncoder( @@ -139,7 +90,6 @@ VideoSender::VideoSender( rtcp_feedback_.get(), transport_sender_, NULL, // paced sender. - rtp_video_sender_statistics_.get(), NULL, video_config.rtcp_mode, base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), @@ -157,6 +107,9 @@ VideoSender::VideoSender( cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber_); memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); + + transport_sender_->SubscribeVideoRtpStatsCallback( + base::Bind(&VideoSender::StoreStatistics, weak_factory_.GetWeakPtr())); } VideoSender::~VideoSender() { @@ -167,7 +120,6 @@ void VideoSender::InitializeTimers() { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); if (!initialized_) { initialized_ = true; - ScheduleNextRtcpReport(); ScheduleNextResendCheck(); ScheduleNextSkippedFramesCheck(); } @@ -186,6 +138,13 @@ void VideoSender::InsertRawVideoFrame( GetVideoRtpTimestamp(capture_time), kFrameIdUnknown); + // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc + TRACE_EVENT_INSTANT2( + "cast_perf_test", "InsertRawVideoFrame", + TRACE_EVENT_SCOPE_THREAD, + "timestamp", capture_time.ToInternalValue(), + "rtp_timestamp", GetVideoRtpTimestamp(capture_time)); + if (!video_encoder_->EncodeVideoFrame( video_frame, capture_time, @@ -210,6 +169,12 @@ void VideoSender::SendEncodedVideoFrameMainThread( encoded_frame->rtp_timestamp, frame_id); + // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc + TRACE_EVENT_INSTANT1( + "cast_perf_test", "VideoFrameEncoded", + TRACE_EVENT_SCOPE_THREAD, + "rtp_timestamp", GetVideoRtpTimestamp(capture_time)); + // Only use lowest 8 bits as key. frame_id_to_rtp_timestamp_[frame_id & 0xff] = encoded_frame->rtp_timestamp; @@ -252,6 +217,13 @@ void VideoSender::ScheduleNextRtcpReport() { time_to_next); } +void VideoSender::StoreStatistics( + const transport::RtcpSenderInfo& sender_info, + base::TimeTicks time_sent, + uint32 rtp_timestamp) { + rtp_stats_.Store(sender_info, time_sent, rtp_timestamp); +} + void VideoSender::SendRtcpReport() { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); @@ -292,7 +264,9 @@ void VideoSender::SendRtcpReport() { } } - rtcp_->SendRtcpFromRtpSender(sender_log_message); + rtp_stats_.UpdateInfo(cast_environment_->Clock()->NowTicks()); + + rtcp_->SendRtcpFromRtpSender(sender_log_message, rtp_stats_.sender_info()); if (!sender_log_message.empty()) { VLOG(1) << "Failed to send all log messages"; } @@ -447,6 +421,11 @@ void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { void VideoSender::ReceivedAck(uint32 acked_frame_id) { DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); + // Start sending RTCP packets only after receiving the first ACK, i.e. only + // after establishing that the receiver is active. + if (last_acked_frame_id_ == -1) { + ScheduleNextRtcpReport(); + } last_acked_frame_id_ = static_cast(acked_frame_id); base::TimeTicks now = cast_environment_->Clock()->NowTicks(); diff --git a/media/cast/video_sender/video_sender.h b/media/cast/video_sender/video_sender.h index b68ac6764c..5b436dca7f 100644 --- a/media/cast/video_sender/video_sender.h +++ b/media/cast/video_sender/video_sender.h @@ -25,9 +25,7 @@ namespace media { class VideoFrame; namespace cast { - class LocalRtcpVideoSenderFeedback; -class LocalRtpVideoSenderStatistics; class LocalVideoEncoderCallback; class VideoEncoder; @@ -62,6 +60,11 @@ class VideoSender : public base::NonThreadSafe, // Only called from the main cast thread. void IncomingRtcpPacket(scoped_ptr packet); + // Store rtp stats computed at the Cast transport sender. + void StoreStatistics(const transport::RtcpSenderInfo& sender_info, + base::TimeTicks time_sent, + uint32 rtp_timestamp); + protected: // Protected for testability. void OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback); @@ -116,9 +119,8 @@ class VideoSender : public base::NonThreadSafe, // Subscribes to raw events. // Processes raw audio events to be sent over to the cast receiver via RTCP. SenderRtcpEventSubscriber event_subscriber_; - + RtpSenderStatistics rtp_stats_; scoped_ptr rtcp_feedback_; - scoped_ptr rtp_video_sender_statistics_; scoped_ptr video_encoder_; scoped_ptr rtcp_; uint8 max_unacked_frames_; @@ -141,6 +143,8 @@ class VideoSender : public base::NonThreadSafe, bool initialized_; // Indicator for receiver acknowledgments. bool active_session_; + + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(VideoSender); diff --git a/media/cast/video_sender/video_sender_unittest.cc b/media/cast/video_sender/video_sender_unittest.cc index 0bd4f2f3e5..8847013fab 100644 --- a/media/cast/video_sender/video_sender_unittest.cc +++ b/media/cast/video_sender/video_sender_unittest.cc @@ -98,7 +98,6 @@ class VideoSenderTest : public ::testing::Test { NULL, testing_clock_, dummy_endpoint, - dummy_endpoint, logging_config, base::Bind(&UpdateCastTransportStatus), transport::BulkRawEventsCallback(), @@ -230,6 +229,14 @@ TEST_F(VideoSenderTest, RtcpTimer) { RunTasks(max_rtcp_timeout.InMilliseconds()); EXPECT_GE(transport_.number_of_rtp_packets(), 1); + // Don't send RTCP prior to receiving an ACK. + EXPECT_GE(transport_.number_of_rtcp_packets(), 0); + // 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_GE(transport_.number_of_rtcp_packets(), 1); } -- cgit v1.2.3