diff options
Diffstat (limited to 'modules/rtp_rtcp/source')
-rw-r--r-- | modules/rtp_rtcp/source/rtp_sender.cc | 80 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_sender.h | 10 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_sender_unittest.cc | 22 |
3 files changed, 81 insertions, 31 deletions
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc index 0438b9f7..677f3fc4 100644 --- a/modules/rtp_rtcp/source/rtp_sender.cc +++ b/modules/rtp_rtcp/source/rtp_sender.cc @@ -40,6 +40,57 @@ const char* FrameTypeToString(const FrameType frame_type) { } // namespace +class BitrateAggregator { + public: + explicit BitrateAggregator(BitrateStatisticsObserver* bitrate_callback) + : callback_(bitrate_callback), + total_bitrate_observer_(*this), + retransmit_bitrate_observer_(*this), + ssrc_(0) {} + + void OnStatsUpdated() const { + if (callback_) + callback_->Notify(total_bitrate_observer_.statistics(), + retransmit_bitrate_observer_.statistics(), + ssrc_); + } + + Bitrate::Observer* total_bitrate_observer() { + return &total_bitrate_observer_; + } + Bitrate::Observer* retransmit_bitrate_observer() { + return &retransmit_bitrate_observer_; + } + + void set_ssrc(uint32_t ssrc) { ssrc_ = ssrc; } + + private: + // We assume that these observers are called on the same thread, which is + // true for RtpSender as they are called on the Process thread. + class BitrateObserver : public Bitrate::Observer { + public: + explicit BitrateObserver(const BitrateAggregator& aggregator) + : aggregator_(aggregator) {} + + // Implements Bitrate::Observer. + virtual void BitrateUpdated(const BitrateStatistics& stats) OVERRIDE { + statistics_ = stats; + aggregator_.OnStatsUpdated(); + } + + BitrateStatistics statistics() const { return statistics_; } + + private: + BitrateStatistics statistics_; + const BitrateAggregator& aggregator_; + }; + + BitrateStatisticsObserver* const callback_; + BitrateObserver total_bitrate_observer_; + BitrateObserver retransmit_bitrate_observer_; + uint32_t ssrc_; +}; + RTPSender::RTPSender(const int32_t id, const bool audio, Clock* clock, @@ -54,7 +105,8 @@ RTPSender::RTPSender(const int32_t id, // TickTime. clock_delta_ms_(clock_->TimeInMilliseconds() - TickTime::MillisecondTimestamp()), - bitrate_sent_(clock, this), + bitrates_(new BitrateAggregator(bitrate_callback)), + total_bitrate_sent_(clock, bitrates_->total_bitrate_observer()), id_(id), audio_configured_(audio), audio_(NULL), @@ -74,12 +126,11 @@ RTPSender::RTPSender(const int32_t id, // NACK. nack_byte_count_times_(), nack_byte_count_(), - nack_bitrate_(clock, NULL), + nack_bitrate_(clock, bitrates_->retransmit_bitrate_observer()), packet_history_(clock), // Statistics statistics_crit_(CriticalSectionWrapper::CreateCriticalSection()), rtp_stats_callback_(NULL), - bitrate_callback_(bitrate_callback), frame_count_observer_(frame_count_observer), send_side_delay_observer_(send_side_delay_observer), // RTP variables @@ -108,6 +159,7 @@ RTPSender::RTPSender(const int32_t id, srand(static_cast<uint32_t>(clock_->TimeInMilliseconds())); ssrc_ = ssrc_db_.CreateSSRC(); // Can't be 0. ssrc_rtx_ = ssrc_db_.CreateSSRC(); // Can't be 0. + bitrates_->set_ssrc(ssrc_); // Random start, 16 bits. Can't be 0. sequence_number_rtx_ = static_cast<uint16_t>(rand() + 1) & 0x7FFF; sequence_number_ = static_cast<uint16_t>(rand() + 1) & 0x7FFF; @@ -149,7 +201,7 @@ uint32_t RTPSender::GetTargetBitrate() { } uint16_t RTPSender::ActualSendBitrateKbit() const { - return (uint16_t)(bitrate_sent_.BitrateNow() / 1000); + return (uint16_t)(total_bitrate_sent_.BitrateNow() / 1000); } uint32_t RTPSender::VideoBitrateSent() const { @@ -864,7 +916,7 @@ void RTPSender::UpdateRtpStats(const uint8_t* buffer, counters = &rtp_stats_; } - bitrate_sent_.Update(size); + total_bitrate_sent_.Update(size); ++counters->packets; if (IsFecPacket(buffer, header)) { ++counters->fec_packets; @@ -997,7 +1049,7 @@ void RTPSender::UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms) { void RTPSender::ProcessBitrate() { CriticalSectionScoped cs(send_critsect_); - bitrate_sent_.Process(); + total_bitrate_sent_.Process(); nack_bitrate_.Process(); if (audio_configured_) { return; @@ -1420,6 +1472,7 @@ void RTPSender::SetSendingStatus(bool enabled) { // Generate a new SSRC. ssrc_db_.ReturnSSRC(ssrc_); ssrc_ = ssrc_db_.CreateSSRC(); // Can't be 0. + bitrates_->set_ssrc(ssrc_); } // Don't initialize seq number if SSRC passed externally. if (!sequence_number_forced_ && !ssrc_forced_) { @@ -1470,6 +1523,7 @@ uint32_t RTPSender::GenerateNewSSRC() { return 0; } ssrc_ = ssrc_db_.CreateSSRC(); // Can't be 0. + bitrates_->set_ssrc(ssrc_); return ssrc_; } @@ -1484,6 +1538,7 @@ void RTPSender::SetSSRC(uint32_t ssrc) { ssrc_db_.ReturnSSRC(ssrc_); ssrc_db_.RegisterSSRC(ssrc); ssrc_ = ssrc; + bitrates_->set_ssrc(ssrc_); if (!sequence_number_forced_) { sequence_number_ = rand() / (RAND_MAX / MAX_INIT_RTP_SEQ_NUMBER); // NOLINT @@ -1681,17 +1736,8 @@ StreamDataCountersCallback* RTPSender::GetRtpStatisticsCallback() const { return rtp_stats_callback_; } -uint32_t RTPSender::BitrateSent() const { return bitrate_sent_.BitrateLast(); } - -void RTPSender::BitrateUpdated(const BitrateStatistics& stats) { - uint32_t ssrc; - { - CriticalSectionScoped ssrc_lock(send_critsect_); - ssrc = ssrc_; - } - if (bitrate_callback_) { - bitrate_callback_->Notify(stats, ssrc); - } +uint32_t RTPSender::BitrateSent() const { + return total_bitrate_sent_.BitrateLast(); } void RTPSender::SetRtpState(const RtpState& rtp_state) { diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h index 780baa1f..6564d47b 100644 --- a/modules/rtp_rtcp/source/rtp_sender.h +++ b/modules/rtp_rtcp/source/rtp_sender.h @@ -31,6 +31,7 @@ namespace webrtc { +class BitrateAggregator; class CriticalSectionWrapper; class RTPSenderAudio; class RTPSenderVideo; @@ -65,7 +66,7 @@ class RTPSenderInterface { PacedSender::Priority priority) = 0; }; -class RTPSender : public RTPSenderInterface, public Bitrate::Observer { +class RTPSender : public RTPSenderInterface { public: RTPSender(const int32_t id, const bool audio, Clock *clock, Transport *transport, RtpAudioFeedback *audio_feedback, @@ -276,8 +277,6 @@ class RTPSender : public RTPSenderInterface, public Bitrate::Observer { uint32_t BitrateSent() const; - virtual void BitrateUpdated(const BitrateStatistics& stats) OVERRIDE; - void SetRtpState(const RtpState& rtp_state); RtpState GetRtpState() const; void SetRtxRtpState(const RtpState& rtp_state); @@ -337,7 +336,9 @@ class RTPSender : public RTPSenderInterface, public Bitrate::Observer { Clock* clock_; int64_t clock_delta_ms_; - Bitrate bitrate_sent_; + + scoped_ptr<BitrateAggregator> bitrates_; + Bitrate total_bitrate_sent_; int32_t id_; const bool audio_configured_; @@ -375,7 +376,6 @@ class RTPSender : public RTPSenderInterface, public Bitrate::Observer { StreamDataCounters rtp_stats_ GUARDED_BY(statistics_crit_); StreamDataCounters rtx_rtp_stats_ GUARDED_BY(statistics_crit_); StreamDataCountersCallback* rtp_stats_callback_ GUARDED_BY(statistics_crit_); - BitrateStatisticsObserver* const bitrate_callback_; FrameCountObserver* const frame_count_observer_; SendSideDelayObserver* const send_side_delay_observer_; diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc index 9c6a7207..2a494778 100644 --- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -855,20 +855,22 @@ TEST_F(RtpSenderTest, FrameCountCallbacks) { TEST_F(RtpSenderTest, BitrateCallbacks) { class TestCallback : public BitrateStatisticsObserver { public: - TestCallback() - : BitrateStatisticsObserver(), num_calls_(0), ssrc_(0), bitrate_() {} + TestCallback() : BitrateStatisticsObserver(), num_calls_(0), ssrc_(0) {} virtual ~TestCallback() {} - virtual void Notify(const BitrateStatistics& stats, + virtual void Notify(const BitrateStatistics& total_stats, + const BitrateStatistics& retransmit_stats, uint32_t ssrc) OVERRIDE { ++num_calls_; ssrc_ = ssrc; - bitrate_ = stats; + total_stats_ = total_stats; + retransmit_stats_ = retransmit_stats; } uint32_t num_calls_; uint32_t ssrc_; - BitrateStatistics bitrate_; + BitrateStatistics total_stats_; + BitrateStatistics retransmit_stats_; } callback; rtp_sender_.reset(new RTPSender(0, false, &fake_clock_, &transport_, NULL, &mock_paced_sender_, &callback, NULL, NULL)); @@ -909,13 +911,15 @@ TEST_F(RtpSenderTest, BitrateCallbacks) { const uint32_t expected_packet_rate = 1000 / kPacketInterval; - EXPECT_EQ(1U, callback.num_calls_); + // We get one call for every stats updated, thus two calls since both the + // stream stats and the retransmit stats are updated once. + EXPECT_EQ(2u, callback.num_calls_); EXPECT_EQ(ssrc, callback.ssrc_); EXPECT_EQ(start_time + (kNumPackets * kPacketInterval), - callback.bitrate_.timestamp_ms); - EXPECT_EQ(expected_packet_rate, callback.bitrate_.packet_rate); + callback.total_stats_.timestamp_ms); + EXPECT_EQ(expected_packet_rate, callback.total_stats_.packet_rate); EXPECT_EQ((kPacketOverhead + sizeof(payload)) * 8 * expected_packet_rate, - callback.bitrate_.bitrate_bps); + callback.total_stats_.bitrate_bps); rtp_sender_.reset(); } |