From ce4e9a356200170abcdd44ff2af95f87a6781b8e Mon Sep 17 00:00:00 2001 From: "pbos@webrtc.org" Date: Thu, 18 Dec 2014 13:50:16 +0000 Subject: [PATCH] Refactor some receive-side stats. Removes polling of CName as well as receive codec statistics in favor of internal callbacks keeping a statistics struct up to date. R=mflodman@webrtc.org, stefan@webrtc.org BUG=1667 Review URL: https://webrtc-codereview.appspot.com/28259005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7950 4adac7df-926f-26a2-2b94-8c16560cd09d --- talk/media/webrtc/fakewebrtcvideoengine.h | 3 ++ webrtc/common_types.h | 13 +++++--- webrtc/config.h | 7 ++--- webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h | 4 +-- webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h | 6 ++-- .../source/receive_statistics_impl.cc | 9 ++++-- .../rtp_rtcp/source/receive_statistics_impl.h | 1 + .../source/receive_statistics_unittest.cc | 2 ++ .../modules/rtp_rtcp/source/rtcp_receiver.cc | 4 +++ .../rtp_rtcp/source/rtcp_receiver_unittest.cc | 2 ++ .../modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 6 ++-- .../modules/rtp_rtcp/source/rtp_rtcp_impl.h | 5 ++- webrtc/modules/rtp_rtcp/source/rtp_sender.cc | 9 ++++-- webrtc/modules/rtp_rtcp/source/rtp_sender.h | 2 +- .../rtp_rtcp/source/rtp_sender_unittest.cc | 31 ++++++------------- .../main/interface/video_coding.h | 12 ++----- .../video_coding/main/source/jitter_buffer.cc | 30 +++++++++++++----- .../video_coding/main/source/jitter_buffer.h | 10 ++++-- .../main/source/jitter_buffer_unittest.cc | 10 +++--- .../video_coding/main/source/receiver.cc | 13 ++++---- .../video_coding/main/source/receiver.h | 3 +- .../main/source/video_coding_impl.cc | 9 +++--- .../main/source/video_coding_impl.h | 2 +- .../main/source/video_receiver.cc | 9 +++--- webrtc/video/end_to_end_tests.cc | 12 +++++-- webrtc/video/receive_statistics_proxy.cc | 28 +++++++---------- webrtc/video/receive_statistics_proxy.h | 17 +++++----- webrtc/video/send_statistics_proxy.cc | 21 ++++--------- webrtc/video/send_statistics_proxy.h | 6 ++-- .../video/send_statistics_proxy_unittest.cc | 26 +++++++++------- webrtc/video/video_receive_stream.cc | 16 +++++++--- webrtc/video/video_send_stream_tests.cc | 7 +++-- webrtc/video_engine/include/vie_base.h | 5 +++ webrtc/video_engine/vie_base_impl.cc | 13 ++++++++ webrtc/video_engine/vie_base_impl.h | 3 ++ webrtc/video_engine/vie_channel.cc | 31 ++++++++++--------- webrtc/video_engine/vie_channel.h | 24 ++++++++++---- webrtc/voice_engine/channel.cc | 2 ++ 38 files changed, 235 insertions(+), 178 deletions(-) diff --git a/talk/media/webrtc/fakewebrtcvideoengine.h b/talk/media/webrtc/fakewebrtcvideoengine.h index 28edf1da76..e8a3f09844 100644 --- a/talk/media/webrtc/fakewebrtcvideoengine.h +++ b/talk/media/webrtc/fakewebrtcvideoengine.h @@ -727,6 +727,9 @@ class FakeWebRtcVideoEngine WEBRTC_VOID_STUB(RegisterSendStatisticsProxy, (int, webrtc::SendStatisticsProxy*)); + WEBRTC_VOID_STUB(RegisterReceiveStatisticsProxy, + (int, webrtc::ReceiveStatisticsProxy*)); + // webrtc::ViECodec WEBRTC_FUNC_CONST(NumberOfCodecs, ()) { return num_codecs_; diff --git a/webrtc/common_types.h b/webrtc/common_types.h index e647aadd34..a4fe914352 100644 --- a/webrtc/common_types.h +++ b/webrtc/common_types.h @@ -188,13 +188,13 @@ struct RtcpStatistics { uint32_t jitter; }; -// Callback, called whenever a new rtcp report block is transmitted. class RtcpStatisticsCallback { public: virtual ~RtcpStatisticsCallback() {} virtual void StatisticsUpdated(const RtcpStatistics& statistics, uint32_t ssrc) = 0; + virtual void CNameChanged(const char* cname, uint32_t ssrc) = 0; }; // Statistics for RTCP packet types. @@ -331,13 +331,18 @@ class BitrateStatisticsObserver { uint32_t ssrc) = 0; }; +struct FrameCounts { + FrameCounts() : key_frames(0), delta_frames(0) {} + int key_frames; + int delta_frames; +}; + // Callback, used to notify an observer whenever frame counts have been updated. class FrameCountObserver { public: virtual ~FrameCountObserver() {} - virtual void FrameCountUpdated(FrameType frame_type, - uint32_t frame_count, - const unsigned int ssrc) = 0; + virtual void FrameCountUpdated(const FrameCounts& frame_counts, + uint32_t ssrc) = 0; }; // Callback, used to notify an observer whenever the send-side delay is updated. diff --git a/webrtc/config.h b/webrtc/config.h index cf41ae66dc..cd5a23ffc1 100644 --- a/webrtc/config.h +++ b/webrtc/config.h @@ -23,16 +23,13 @@ namespace webrtc { struct SsrcStats { SsrcStats() - : key_frames(0), - delta_frames(0), - sent_width(0), + : sent_width(0), sent_height(0), total_bitrate_bps(0), retransmit_bitrate_bps(0), avg_delay_ms(0), max_delay_ms(0) {} - uint32_t key_frames; - uint32_t delta_frames; + FrameCounts frame_counts; int sent_width; int sent_height; // TODO(holmer): Move bitrate_bps out to the webrtc::Call layer. diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h index bff099d7a3..745c908398 100644 --- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h +++ b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h @@ -586,10 +586,10 @@ class RtpRtcp : public Module { virtual bool StorePackets() const = 0; // Called on receipt of RTCP report block from remote side. - virtual void RegisterSendChannelRtcpStatisticsCallback( + virtual void RegisterRtcpStatisticsCallback( RtcpStatisticsCallback* callback) = 0; virtual RtcpStatisticsCallback* - GetSendChannelRtcpStatisticsCallback() = 0; + GetRtcpStatisticsCallback() = 0; /************************************************************************** * diff --git a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h index 25175b3194..859d3e3a3d 100644 --- a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h +++ b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h @@ -221,10 +221,8 @@ class MockRtpRtcp : public RtpRtcp { MOCK_METHOD2(SetStorePacketsStatus, int32_t(const bool enable, const uint16_t numberToStore)); MOCK_CONST_METHOD0(StorePackets, bool()); - MOCK_METHOD1(RegisterSendChannelRtcpStatisticsCallback, - void(RtcpStatisticsCallback*)); - MOCK_METHOD0(GetSendChannelRtcpStatisticsCallback, - RtcpStatisticsCallback*()); + MOCK_METHOD1(RegisterRtcpStatisticsCallback, void(RtcpStatisticsCallback*)); + MOCK_METHOD0(GetRtcpStatisticsCallback, RtcpStatisticsCallback*()); MOCK_METHOD1(RegisterAudioCallback, int32_t(RtpAudioFeedback* messagesCallback)); MOCK_METHOD1(SetAudioPacketSize, diff --git a/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc b/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc index 7ba83f7c9a..76b2075e60 100644 --- a/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc @@ -511,9 +511,14 @@ void ReceiveStatisticsImpl::RegisterRtcpStatisticsCallback( void ReceiveStatisticsImpl::StatisticsUpdated(const RtcpStatistics& statistics, uint32_t ssrc) { CriticalSectionScoped cs(receive_statistics_lock_.get()); - if (rtcp_stats_callback_) { + if (rtcp_stats_callback_) rtcp_stats_callback_->StatisticsUpdated(statistics, ssrc); - } +} + +void ReceiveStatisticsImpl::CNameChanged(const char* cname, uint32_t ssrc) { + CriticalSectionScoped cs(receive_statistics_lock_.get()); + if (rtcp_stats_callback_) + rtcp_stats_callback_->CNameChanged(cname, ssrc); } void ReceiveStatisticsImpl::RegisterRtpStatisticsCallback( diff --git a/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h b/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h index 0228925816..22e42eadba 100644 --- a/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h +++ b/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h @@ -128,6 +128,7 @@ class ReceiveStatisticsImpl : public ReceiveStatistics, private: virtual void StatisticsUpdated(const RtcpStatistics& statistics, uint32_t ssrc) OVERRIDE; + virtual void CNameChanged(const char* cname, uint32_t ssrc) OVERRIDE; virtual void DataCountersUpdated(const StreamDataCounters& counters, uint32_t ssrc) OVERRIDE; diff --git a/webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc b/webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc index 93351e53b0..5b2f0e3099 100644 --- a/webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc @@ -169,6 +169,8 @@ TEST_F(ReceiveStatisticsTest, RtcpCallbacks) { ++num_calls_; } + virtual void CNameChanged(const char* cname, uint32_t ssrc) OVERRIDE {} + uint32_t num_calls_; uint32_t ssrc_; RtcpStatistics stats_; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc index 8149370170..b03b68ffe6 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -809,6 +809,10 @@ void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) { cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0; strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1); + if (stats_callback_ != NULL) { + stats_callback_->CNameChanged(rtcpPacket.CName.CName, + rtcpPacket.CName.SenderSSRC); + } } // no need for critsect we have _criticalSectionRTCPReceiver diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc index d65157d65a..f0ffd9ee79 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc @@ -820,6 +820,8 @@ TEST_F(RtcpReceiverTest, Callbacks) { ssrc_ = ssrc; } + virtual void CNameChanged(const char* cname, uint32_t ssrc) OVERRIDE {} + bool Matches(uint32_t ssrc, uint32_t extended_max, uint8_t fraction_loss, uint32_t cumulative_loss, uint32_t jitter) { return ssrc_ == ssrc && diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 5f1277345f..6877e830a4 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -988,13 +988,13 @@ bool ModuleRtpRtcpImpl::StorePackets() const { return rtp_sender_.StorePackets(); } -void ModuleRtpRtcpImpl::RegisterSendChannelRtcpStatisticsCallback( +void ModuleRtpRtcpImpl::RegisterRtcpStatisticsCallback( RtcpStatisticsCallback* callback) { rtcp_receiver_.RegisterRtcpStatisticsCallback(callback); } -RtcpStatisticsCallback* ModuleRtpRtcpImpl:: - GetSendChannelRtcpStatisticsCallback() { +RtcpStatisticsCallback* +ModuleRtpRtcpImpl::GetRtcpStatisticsCallback() { return rtcp_receiver_.GetRtcpStatisticsCallback(); } diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h index cb00d6d183..7e7b0df662 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -247,10 +247,9 @@ class ModuleRtpRtcpImpl : public RtpRtcp { virtual bool StorePackets() const OVERRIDE; // Called on receipt of RTCP report block from remote side. - virtual void RegisterSendChannelRtcpStatisticsCallback( + virtual void RegisterRtcpStatisticsCallback( RtcpStatisticsCallback* callback) OVERRIDE; - virtual RtcpStatisticsCallback* - GetSendChannelRtcpStatisticsCallback() OVERRIDE; + virtual RtcpStatisticsCallback* GetRtcpStatisticsCallback() OVERRIDE; // (APP) Application specific data. virtual int32_t SetRTCPApplicationSpecificData( diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc index 3d2dfbe08c..2a95dc9c30 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc @@ -502,9 +502,14 @@ int32_t RTPSender::SendOutgoingData( } CriticalSectionScoped cs(statistics_crit_.get()); - uint32_t frame_count = ++frame_counts_[frame_type]; + // Note: This is currently only counting for video. + if (frame_type == kVideoFrameKey) { + ++frame_counts_.key_frames; + } else if (frame_type == kVideoFrameDelta) { + ++frame_counts_.delta_frames; + } if (frame_count_observer_) { - frame_count_observer_->FrameCountUpdated(frame_type, frame_count, ssrc); + frame_count_observer_->FrameCountUpdated(frame_counts_, ssrc); } return ret_val; diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h index 795331a60b..978d096789 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h @@ -371,7 +371,7 @@ class RTPSender : public RTPSenderInterface { // Statistics scoped_ptr statistics_crit_; SendDelayMap send_delays_ GUARDED_BY(statistics_crit_); - std::map frame_counts_ GUARDED_BY(statistics_crit_); + FrameCounts frame_counts_ GUARDED_BY(statistics_crit_); StreamDataCounters rtp_stats_ GUARDED_BY(statistics_crit_); StreamDataCounters rtx_rtp_stats_ GUARDED_BY(statistics_crit_); StreamDataCountersCallback* rtp_stats_callback_ GUARDED_BY(statistics_crit_); diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc index 253d1b997c..3946c449c4 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -768,32 +768,19 @@ TEST_F(RtpSenderTest, SendGenericVideo) { TEST_F(RtpSenderTest, FrameCountCallbacks) { class TestCallback : public FrameCountObserver { public: - TestCallback() - : FrameCountObserver(), num_calls_(0), ssrc_(0), - key_frames_(0), delta_frames_(0) {} + TestCallback() : FrameCountObserver(), num_calls_(0), ssrc_(0) {} virtual ~TestCallback() {} - virtual void FrameCountUpdated(FrameType frame_type, - uint32_t frame_count, - const unsigned int ssrc) OVERRIDE { + virtual void FrameCountUpdated(const FrameCounts& frame_counts, + uint32_t ssrc) OVERRIDE { ++num_calls_; ssrc_ = ssrc; - switch (frame_type) { - case kVideoFrameDelta: - delta_frames_ = frame_count; - break; - case kVideoFrameKey: - key_frames_ = frame_count; - break; - default: - break; - } + frame_counts_ = frame_counts; } uint32_t num_calls_; uint32_t ssrc_; - uint32_t key_frames_; - uint32_t delta_frames_; + FrameCounts frame_counts_; } callback; rtp_sender_.reset(new RTPSender(0, false, &fake_clock_, &transport_, NULL, @@ -813,8 +800,8 @@ TEST_F(RtpSenderTest, FrameCountCallbacks) { EXPECT_EQ(1U, callback.num_calls_); EXPECT_EQ(ssrc, callback.ssrc_); - EXPECT_EQ(1U, callback.key_frames_); - EXPECT_EQ(0U, callback.delta_frames_); + EXPECT_EQ(1, callback.frame_counts_.key_frames); + EXPECT_EQ(0, callback.frame_counts_.delta_frames); ASSERT_EQ(0, rtp_sender_->SendOutgoingData(kVideoFrameDelta, payload_type, 1234, 4321, payload, @@ -822,8 +809,8 @@ TEST_F(RtpSenderTest, FrameCountCallbacks) { EXPECT_EQ(2U, callback.num_calls_); EXPECT_EQ(ssrc, callback.ssrc_); - EXPECT_EQ(1U, callback.key_frames_); - EXPECT_EQ(1U, callback.delta_frames_); + EXPECT_EQ(1, callback.frame_counts_.key_frames); + EXPECT_EQ(1, callback.frame_counts_.delta_frames); rtp_sender_.reset(); } diff --git a/webrtc/modules/video_coding/main/interface/video_coding.h b/webrtc/modules/video_coding/main/interface/video_coding.h index 54470f6e58..41b16c22ef 100644 --- a/webrtc/modules/video_coding/main/interface/video_coding.h +++ b/webrtc/modules/video_coding/main/interface/video_coding.h @@ -485,16 +485,6 @@ public: // < 0, on error. virtual int32_t Delay() const = 0; - // Get the received frame counters. Keeps track of the number of each frame type - // received since the start of the call. - // - // Output: - // - frameCount : Struct to be filled with the number of frames received. - // - // Return value : VCM_OK, on success. - // <0, on error. - virtual int32_t ReceivedFrameCount(VCMFrameCount& frameCount) const = 0; - // Returns the number of packets discarded by the jitter buffer due to being // too late. This can include duplicated packets which arrived after the // frame was sent to the decoder. Therefore packets which were prematurely @@ -592,6 +582,8 @@ public: EncodedImageCallback* observer) = 0; virtual void RegisterPostEncodeImageCallback( EncodedImageCallback* post_encode_callback) = 0; + virtual void RegisterReceiveFrameCountObserver( + FrameCountObserver* frame_count_observer) = 0; }; } // namespace webrtc diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer.cc b/webrtc/modules/video_coding/main/source/jitter_buffer.cc index 7a95b71114..6da342dbae 100644 --- a/webrtc/modules/video_coding/main/source/jitter_buffer.cc +++ b/webrtc/modules/video_coding/main/source/jitter_buffer.cc @@ -124,6 +124,7 @@ VCMJitterBuffer::VCMJitterBuffer(Clock* clock, EventFactory* event_factory) incomplete_frames_(), last_decoded_state_(), first_packet_since_reset_(true), + frame_count_observer_(NULL), incoming_frame_rate_(0), incoming_frame_count_(0), time_last_incoming_frame_count_(0), @@ -184,14 +185,15 @@ void VCMJitterBuffer::UpdateHistograms() { RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.DuplicatedPacketsInPercent", num_duplicated_packets_ * 100 / num_packets_); - uint32_t total_frames = receive_statistics_[kVideoFrameKey] + - receive_statistics_[kVideoFrameDelta]; + int total_frames = + receive_statistics_.key_frames + receive_statistics_.delta_frames; if (total_frames > 0) { RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.CompleteFramesReceivedPerSecond", static_cast((total_frames / elapsed_sec) + 0.5f)); - RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille", - static_cast((receive_statistics_[kVideoFrameKey] * 1000.0f / - total_frames) + 0.5f)); + RTC_HISTOGRAM_COUNTS_1000( + "WebRTC.Video.KeyFramesReceivedInPermille", + static_cast( + (receive_statistics_.key_frames * 1000.0f / total_frames) + 0.5f)); } } @@ -203,7 +205,7 @@ void VCMJitterBuffer::Start() { incoming_bit_count_ = 0; incoming_bit_rate_ = 0; time_last_incoming_frame_count_ = clock_->TimeInMilliseconds(); - receive_statistics_.clear(); + receive_statistics_ = FrameCounts(); num_consecutive_old_packets_ = 0; num_packets_ = 0; @@ -269,7 +271,7 @@ void VCMJitterBuffer::Flush() { } // Get received key and delta frames -std::map VCMJitterBuffer::FrameStatistics() const { +FrameCounts VCMJitterBuffer::FrameStatistics() const { CriticalSectionScoped cs(crit_sect_); return receive_statistics_; } @@ -1038,6 +1040,12 @@ void VCMJitterBuffer::RenderBufferSize(uint32_t* timestamp_start, *timestamp_end = decodable_frames_.Back()->TimeStamp(); } +void VCMJitterBuffer::RegisterFrameCountObserver( + FrameCountObserver* frame_count_observer) { + CriticalSectionScoped cs(crit_sect_); + frame_count_observer_ = frame_count_observer; +} + VCMFrameBuffer* VCMJitterBuffer::GetEmptyFrame() { if (free_frames_.empty()) { if (!TryToIncreaseJitterBufferSize()) { @@ -1105,7 +1113,13 @@ void VCMJitterBuffer::CountFrame(const VCMFrameBuffer& frame) { // Update receive statistics. We count all layers, thus when you use layers // adding all key and delta frames might differ from frame count. if (frame.IsSessionComplete()) { - ++receive_statistics_[frame.FrameType()]; + if (frame.FrameType() == kVideoFrameKey) { + ++receive_statistics_.key_frames; + } else { + ++receive_statistics_.delta_frames; + } + if (frame_count_observer_ != NULL) + frame_count_observer_->FrameCountUpdated(receive_statistics_, 0); } } diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer.h b/webrtc/modules/video_coding/main/source/jitter_buffer.h index 3722912cd2..c2833f08df 100644 --- a/webrtc/modules/video_coding/main/source/jitter_buffer.h +++ b/webrtc/modules/video_coding/main/source/jitter_buffer.h @@ -94,7 +94,7 @@ class VCMJitterBuffer { // Get the number of received frames, by type, since the jitter buffer // was started. - std::map FrameStatistics() const; + FrameCounts FrameStatistics() const; // The number of packets discarded by the jitter buffer because the decoder // won't be able to decode them. @@ -184,6 +184,8 @@ class VCMJitterBuffer { // corresponding to the start and end of the continuous complete buffer. void RenderBufferSize(uint32_t* timestamp_start, uint32_t* timestamp_end); + void RegisterFrameCountObserver(FrameCountObserver* observer); + private: class SequenceNumberLessThan { public: @@ -254,7 +256,8 @@ class VCMJitterBuffer { // Updates the frame statistics. // Counts only complete frames, so decodable incomplete frames will not be // counted. - void CountFrame(const VCMFrameBuffer& frame); + void CountFrame(const VCMFrameBuffer& frame) + EXCLUSIVE_LOCKS_REQUIRED(crit_sect_); // Update rolling average of packets per frame. void UpdateAveragePacketsPerFrame(int current_number_packets_); @@ -301,7 +304,8 @@ class VCMJitterBuffer { // Statistics. // Frame counts for each type (key, delta, ...) - std::map receive_statistics_; + FrameCountObserver* frame_count_observer_ GUARDED_BY(crit_sect_); + FrameCounts receive_statistics_; // Latest calculated frame rates of incoming stream. unsigned int incoming_frame_rate_; unsigned int incoming_frame_count_; diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc b/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc index e5561d581d..8ebd5870c3 100644 --- a/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc +++ b/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc @@ -1693,9 +1693,9 @@ TEST_F(TestRunningJitterBuffer, EmptyPackets) { } TEST_F(TestRunningJitterBuffer, StatisticsTest) { - std::map frame_stats(jitter_buffer_->FrameStatistics()); - EXPECT_EQ(0u, frame_stats[kVideoFrameDelta]); - EXPECT_EQ(0u, frame_stats[kVideoFrameKey]); + FrameCounts frame_stats(jitter_buffer_->FrameStatistics()); + EXPECT_EQ(0, frame_stats.delta_frames); + EXPECT_EQ(0, frame_stats.key_frames); uint32_t framerate = 0; uint32_t bitrate = 0; @@ -1714,8 +1714,8 @@ TEST_F(TestRunningJitterBuffer, StatisticsTest) { EXPECT_TRUE(DecodeCompleteFrame()); EXPECT_TRUE(DecodeCompleteFrame()); frame_stats = jitter_buffer_->FrameStatistics(); - EXPECT_EQ(3u, frame_stats[kVideoFrameDelta]); - EXPECT_EQ(2u, frame_stats[kVideoFrameKey]); + EXPECT_EQ(3, frame_stats.delta_frames); + EXPECT_EQ(2, frame_stats.key_frames); // Insert 20 more frames to get estimates of bitrate and framerate over // 1 second. diff --git a/webrtc/modules/video_coding/main/source/receiver.cc b/webrtc/modules/video_coding/main/source/receiver.cc index bb041b3f54..a18488d56a 100644 --- a/webrtc/modules/video_coding/main/source/receiver.cc +++ b/webrtc/modules/video_coding/main/source/receiver.cc @@ -186,13 +186,6 @@ void VCMReceiver::ReceiveStatistics(uint32_t* bitrate, jitter_buffer_.IncomingRateStatistics(framerate, bitrate); } -void VCMReceiver::ReceivedFrameCount(VCMFrameCount* frame_count) const { - assert(frame_count); - std::map counts(jitter_buffer_.FrameStatistics()); - frame_count->numDeltaFrames = counts[kVideoFrameDelta]; - frame_count->numKeyFrames = counts[kVideoFrameKey]; -} - uint32_t VCMReceiver::DiscardedPackets() const { return jitter_buffer_.num_discarded_packets(); } @@ -276,4 +269,10 @@ int VCMReceiver::RenderBufferSizeMs() { uint32_t render_end = timing_->RenderTimeMs(timestamp_end, now_ms); return render_end - render_start; } + +void VCMReceiver::RegisterFrameCountObserver( + FrameCountObserver* frame_count_observer) { + jitter_buffer_.RegisterFrameCountObserver(frame_count_observer); +} + } // namespace webrtc diff --git a/webrtc/modules/video_coding/main/source/receiver.h b/webrtc/modules/video_coding/main/source/receiver.h index 23965f812a..bfe510cf85 100644 --- a/webrtc/modules/video_coding/main/source/receiver.h +++ b/webrtc/modules/video_coding/main/source/receiver.h @@ -53,7 +53,6 @@ class VCMReceiver { bool render_timing = true); void ReleaseFrame(VCMEncodedFrame* frame); void ReceiveStatistics(uint32_t* bitrate, uint32_t* framerate); - void ReceivedFrameCount(VCMFrameCount* frame_count) const; uint32_t DiscardedPackets() const; // NACK. @@ -80,6 +79,8 @@ class VCMReceiver { // the time this function is called. int RenderBufferSizeMs(); + void RegisterFrameCountObserver(FrameCountObserver* frame_count_observer); + private: static int32_t GenerateReceiverId(); diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.cc b/webrtc/modules/video_coding/main/source/video_coding_impl.cc index 751cff68aa..08e7e7327a 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.cc +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.cc @@ -278,6 +278,11 @@ class VideoCodingModuleImpl : public VideoCodingModule { return receiver_->RegisterRenderBufferSizeCallback(callback); } + virtual void RegisterReceiveFrameCountObserver( + FrameCountObserver* frame_count_observer) OVERRIDE { + receiver_->RegisterFrameCountObserver(frame_count_observer); + } + virtual int32_t Decode(uint16_t maxWaitTimeMs) OVERRIDE { return receiver_->Decode(maxWaitTimeMs); } @@ -308,10 +313,6 @@ class VideoCodingModuleImpl : public VideoCodingModule { virtual int32_t Delay() const OVERRIDE { return receiver_->Delay(); } - virtual int32_t ReceivedFrameCount(VCMFrameCount& frameCount) const OVERRIDE { - return receiver_->ReceivedFrameCount(&frameCount); - } - virtual uint32_t DiscardedPackets() const OVERRIDE { return receiver_->DiscardedPackets(); } diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.h b/webrtc/modules/video_coding/main/source/video_coding_impl.h index 71424a6aa8..ed50ef4fd9 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.h +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.h @@ -164,7 +164,6 @@ class VideoReceiver { int32_t SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs); int32_t SetRenderDelay(uint32_t timeMS); int32_t Delay() const; - int32_t ReceivedFrameCount(VCMFrameCount* frameCount) const; uint32_t DiscardedPackets() const; int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode, @@ -183,6 +182,7 @@ class VideoReceiver { int32_t Process(); void RegisterPreDecodeImageCallback(EncodedImageCallback* observer); + void RegisterFrameCountObserver(FrameCountObserver* frame_count_observer); protected: int32_t Decode(const webrtc::VCMEncodedFrame& frame) diff --git a/webrtc/modules/video_coding/main/source/video_receiver.cc b/webrtc/modules/video_coding/main/source/video_receiver.cc index 158931528d..3813205cb0 100644 --- a/webrtc/modules/video_coding/main/source/video_receiver.cc +++ b/webrtc/modules/video_coding/main/source/video_receiver.cc @@ -592,11 +592,6 @@ int32_t VideoReceiver::NackList(uint16_t* nackList, uint16_t* size) { return VCM_OK; } -int32_t VideoReceiver::ReceivedFrameCount(VCMFrameCount* frameCount) const { - _receiver.ReceivedFrameCount(frameCount); - return VCM_OK; -} - uint32_t VideoReceiver::DiscardedPackets() const { return _receiver.DiscardedPackets(); } @@ -671,6 +666,10 @@ void VideoReceiver::RegisterPreDecodeImageCallback( CriticalSectionScoped cs(_receiveCritSect); pre_decode_image_callback_ = observer; } +void VideoReceiver::RegisterFrameCountObserver( + FrameCountObserver* frame_count_observer) { + _receiver.RegisterFrameCountObserver(frame_count_observer); +} } // namespace vcm } // namespace webrtc diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc index 4bf58202fc..51b5bf782f 100644 --- a/webrtc/video/end_to_end_tests.cc +++ b/webrtc/video/end_to_end_tests.cc @@ -1496,8 +1496,13 @@ TEST_F(EndToEndTest, GetStats) { stats.rtp_stats.retransmitted_packets != 0; receive_stats_filled_["CodecStats"] |= - stats.avg_delay_ms != 0 || stats.discarded_packets != 0 || - stats.key_frames != 0 || stats.delta_frames != 0; + stats.avg_delay_ms != 0 || stats.discarded_packets != 0; + + receive_stats_filled_["FrameCounts"] |= + stats.frame_counts.key_frames != 0 || + stats.frame_counts.delta_frames != 0; + + receive_stats_filled_["CName"] |= stats.c_name != ""; return AllStatsFilled(receive_stats_filled_); } @@ -1537,7 +1542,8 @@ TEST_F(EndToEndTest, GetStats) { stream_stats.total_bitrate_bps != 0; send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |= - stream_stats.delta_frames != 0 || stream_stats.key_frames != 0; + stream_stats.frame_counts.delta_frames != 0 || + stream_stats.frame_counts.key_frames != 0; send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |= stats.encode_frame_rate != 0; diff --git a/webrtc/video/receive_statistics_proxy.cc b/webrtc/video/receive_statistics_proxy.cc index 1fbab05049..9d1589d506 100644 --- a/webrtc/video/receive_statistics_proxy.cc +++ b/webrtc/video/receive_statistics_proxy.cc @@ -14,17 +14,14 @@ #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" namespace webrtc { -namespace internal { ReceiveStatisticsProxy::ReceiveStatisticsProxy(uint32_t ssrc, Clock* clock, - ViERTP_RTCP* rtp_rtcp, ViECodec* codec, int channel) : channel_(channel), clock_(clock), codec_(codec), - rtp_rtcp_(rtp_rtcp), crit_(CriticalSectionWrapper::CreateCriticalSection()), // 1000ms window, scale 1000 for ms to s. decode_fps_estimator_(1000, 1000), @@ -40,24 +37,11 @@ VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const { CriticalSectionScoped lock(crit_.get()); stats = stats_; } - stats.c_name = GetCName(); stats.discarded_packets = codec_->GetNumDiscardedPackets(channel_); - codec_->GetReceiveCodecStastistics( - channel_, stats.key_frames, stats.delta_frames); - - codec_->GetReceiveCodecStastistics(channel_, stats.key_frames, - stats.delta_frames); return stats; } -std::string ReceiveStatisticsProxy::GetCName() const { - char rtcp_cname[ViERTP_RTCP::KMaxRTCPCNameLength]; - if (rtp_rtcp_->GetRemoteRTCPCName(channel_, rtcp_cname) != 0) - rtcp_cname[0] = '\0'; - return rtcp_cname; -} - void ReceiveStatisticsProxy::IncomingRate(const int video_channel, const unsigned int framerate, const unsigned int bitrate_bps) { @@ -85,6 +69,11 @@ void ReceiveStatisticsProxy::StatisticsUpdated( stats_.rtcp_stats = statistics; } +void ReceiveStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) { + CriticalSectionScoped lock(crit_.get()); + stats_.c_name = cname; +} + void ReceiveStatisticsProxy::DataCountersUpdated( const webrtc::StreamDataCounters& counters, uint32_t ssrc) { @@ -109,5 +98,10 @@ void ReceiveStatisticsProxy::OnRenderedFrame() { stats_.render_frame_rate = renders_fps_estimator_.Rate(now); } -} // namespace internal +void ReceiveStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts, + uint32_t ssrc) { + CriticalSectionScoped lock(crit_.get()); + stats_.frame_counts = frame_counts; +} + } // namespace webrtc diff --git a/webrtc/video/receive_statistics_proxy.h b/webrtc/video/receive_statistics_proxy.h index 85a3813e0d..c61d6eaac5 100644 --- a/webrtc/video/receive_statistics_proxy.h +++ b/webrtc/video/receive_statistics_proxy.h @@ -29,15 +29,13 @@ class CriticalSectionWrapper; class ViECodec; class ViEDecoderObserver; -namespace internal { - class ReceiveStatisticsProxy : public ViEDecoderObserver, public RtcpStatisticsCallback, - public StreamDataCountersCallback { + public StreamDataCountersCallback, + public FrameCountObserver { public: ReceiveStatisticsProxy(uint32_t ssrc, Clock* clock, - ViERTP_RTCP* rtp_rtcp, ViECodec* codec, int channel); virtual ~ReceiveStatisticsProxy(); @@ -62,21 +60,23 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver, int render_delay_ms) OVERRIDE; virtual void RequestNewKeyFrame(const int video_channel) OVERRIDE {} - // Overrides RtcpStatisticsBallback. + // Overrides RtcpStatisticsCallback. virtual void StatisticsUpdated(const webrtc::RtcpStatistics& statistics, uint32_t ssrc) OVERRIDE; + virtual void CNameChanged(const char* cname, uint32_t ssrc) OVERRIDE; // Overrides StreamDataCountersCallback. virtual void DataCountersUpdated(const webrtc::StreamDataCounters& counters, uint32_t ssrc) OVERRIDE; - private: - std::string GetCName() const; + // Overrides FrameCountObserver. + virtual void FrameCountUpdated(const FrameCounts& frame_counts, + uint32_t ssrc) OVERRIDE; + private: const int channel_; Clock* const clock_; ViECodec* const codec_; - ViERTP_RTCP* const rtp_rtcp_; scoped_ptr crit_; VideoReceiveStream::Stats stats_ GUARDED_BY(crit_); @@ -84,6 +84,5 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver, RateStatistics renders_fps_estimator_ GUARDED_BY(crit_); }; -} // namespace internal } // namespace webrtc #endif // WEBRTC_VIDEO_RECEIVE_STATISTICS_PROXY_H_ diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc index d590be1fac..b593c4dd3d 100644 --- a/webrtc/video/send_statistics_proxy.cc +++ b/webrtc/video/send_statistics_proxy.cc @@ -115,6 +115,9 @@ void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics, stats->rtcp_stats = statistics; } +void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) { +} + void SendStatisticsProxy::DataCountersUpdated( const StreamDataCounters& counters, uint32_t ssrc) { @@ -138,26 +141,14 @@ void SendStatisticsProxy::Notify(const BitrateStatistics& total_stats, stats->retransmit_bitrate_bps = retransmit_stats.bitrate_bps; } -void SendStatisticsProxy::FrameCountUpdated(FrameType frame_type, - uint32_t frame_count, - const unsigned int ssrc) { +void SendStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts, + uint32_t ssrc) { CriticalSectionScoped lock(crit_.get()); SsrcStats* stats = GetStatsEntry(ssrc); if (stats == NULL) return; - switch (frame_type) { - case kVideoFrameDelta: - stats->delta_frames = frame_count; - break; - case kVideoFrameKey: - stats->key_frames = frame_count; - break; - case kFrameEmpty: - case kAudioFrameSpeech: - case kAudioFrameCN: - break; - } + stats->frame_counts = frame_counts; } void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms, diff --git a/webrtc/video/send_statistics_proxy.h b/webrtc/video/send_statistics_proxy.h index 5e7d208202..ac6e309d97 100644 --- a/webrtc/video/send_statistics_proxy.h +++ b/webrtc/video/send_statistics_proxy.h @@ -48,6 +48,7 @@ class SendStatisticsProxy : public RtcpStatisticsCallback, // From RtcpStatisticsCallback. virtual void StatisticsUpdated(const RtcpStatistics& statistics, uint32_t ssrc) OVERRIDE; + virtual void CNameChanged(const char *cname, uint32_t ssrc) OVERRIDE; // From StreamDataCountersCallback. virtual void DataCountersUpdated(const StreamDataCounters& counters, uint32_t ssrc) OVERRIDE; @@ -58,9 +59,8 @@ class SendStatisticsProxy : public RtcpStatisticsCallback, uint32_t ssrc) OVERRIDE; // From FrameCountObserver. - virtual void FrameCountUpdated(FrameType frame_type, - uint32_t frame_count, - const unsigned int ssrc) OVERRIDE; + virtual void FrameCountUpdated(const FrameCounts& frame_counts, + uint32_t ssrc) OVERRIDE; // From ViEEncoderObserver. virtual void OutgoingRate(const int video_channel, diff --git a/webrtc/video/send_statistics_proxy_unittest.cc b/webrtc/video/send_statistics_proxy_unittest.cc index 4ee2cc6c62..ccc0192e45 100644 --- a/webrtc/video/send_statistics_proxy_unittest.cc +++ b/webrtc/video/send_statistics_proxy_unittest.cc @@ -59,8 +59,8 @@ class SendStatisticsProxyTest : public ::testing::Test { const SsrcStats& a = it->second; const SsrcStats& b = corresponding_it->second; - EXPECT_EQ(a.key_frames, b.key_frames); - EXPECT_EQ(a.delta_frames, b.delta_frames); + EXPECT_EQ(a.frame_counts.key_frames, b.frame_counts.key_frames); + EXPECT_EQ(a.frame_counts.delta_frames, b.frame_counts.delta_frames); EXPECT_EQ(a.total_bitrate_bps, b.total_bitrate_bps); EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms); EXPECT_EQ(a.max_delay_ms, b.max_delay_ms); @@ -169,10 +169,11 @@ TEST_F(SendStatisticsProxyTest, FrameCounts) { // Add statistics with some arbitrary, but unique, numbers. SsrcStats& stats = expected_.substreams[ssrc]; uint32_t offset = ssrc * sizeof(SsrcStats); - stats.key_frames = offset; - stats.delta_frames = offset + 1; - observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc); - observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc); + FrameCounts frame_counts; + frame_counts.key_frames = offset; + frame_counts.delta_frames = offset + 1; + stats.frame_counts = frame_counts; + observer->FrameCountUpdated(frame_counts, ssrc); } for (std::vector::const_iterator it = config_.rtp.rtx.ssrcs.begin(); it != config_.rtp.rtx.ssrcs.end(); @@ -181,10 +182,11 @@ TEST_F(SendStatisticsProxyTest, FrameCounts) { // Add statistics with some arbitrary, but unique, numbers. SsrcStats& stats = expected_.substreams[ssrc]; uint32_t offset = ssrc * sizeof(SsrcStats); - stats.key_frames = offset; - stats.delta_frames = offset + 1; - observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc); - observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc); + FrameCounts frame_counts; + frame_counts.key_frames = offset; + frame_counts.delta_frames = offset + 1; + stats.frame_counts = frame_counts; + observer->FrameCountUpdated(frame_counts, ssrc); } VideoSendStream::Stats stats = statistics_proxy_->GetStats(); @@ -318,7 +320,9 @@ TEST_F(SendStatisticsProxyTest, NoSubstreams) { // From FrameCountObserver. FrameCountObserver* fps_observer = statistics_proxy_.get(); - fps_observer->FrameCountUpdated(kVideoFrameKey, 1, exluded_ssrc); + FrameCounts frame_counts; + frame_counts.key_frames = 1; + fps_observer->FrameCountUpdated(frame_counts, exluded_ssrc); VideoSendStream::Stats stats = statistics_proxy_->GetStats(); EXPECT_TRUE(stats.substreams.empty()); diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc index 3fc24a34d6..55e0867742 100644 --- a/webrtc/video/video_receive_stream.cc +++ b/webrtc/video/video_receive_stream.cc @@ -148,19 +148,25 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine, } } - stats_proxy_.reset(new ReceiveStatisticsProxy( - config_.rtp.local_ssrc, clock_, rtp_rtcp_, codec_, channel_)); + stats_proxy_.reset(new ReceiveStatisticsProxy(config_.rtp.local_ssrc, clock_, + codec_, channel_)); if (rtp_rtcp_->RegisterReceiveChannelRtcpStatisticsCallback( - channel_, stats_proxy_.get()) != 0) + channel_, stats_proxy_.get()) != 0) { abort(); + } if (rtp_rtcp_->RegisterReceiveChannelRtpStatisticsCallback( - channel_, stats_proxy_.get()) != 0) + channel_, stats_proxy_.get()) != 0) { abort(); + } - if (codec_->RegisterDecoderObserver(channel_, *stats_proxy_) != 0) + if (codec_->RegisterDecoderObserver(channel_, *stats_proxy_) != 0) { abort(); + } + + video_engine_base_->RegisterReceiveStatisticsProxy(channel_, + stats_proxy_.get()); external_codec_ = ViEExternalCodec::GetInterface(video_engine); assert(!config_.decoders.empty()); diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc index a94a379fa0..915bf9e35f 100644 --- a/webrtc/video/video_send_stream_tests.cc +++ b/webrtc/video/video_send_stream_tests.cc @@ -958,9 +958,10 @@ TEST_F(VideoSendStreamTest, ProducesStats) { // Check for data populated by various sources. RTCP excluded as this // data is received from remote side. Tested in call tests instead. const SsrcStats& entry = stats.substreams[ssrc]; - if (entry.key_frames > 0u && entry.total_bitrate_bps > 0 && - entry.rtp_stats.packets > 0u && entry.avg_delay_ms > 0 && - entry.max_delay_ms > 0) { + if (entry.frame_counts.key_frames > 0 && + entry.frame_counts.delta_frames > 0 && + entry.total_bitrate_bps > 0 && entry.rtp_stats.packets > 0u && + entry.avg_delay_ms > 0 && entry.max_delay_ms > 0) { return true; } } diff --git a/webrtc/video_engine/include/vie_base.h b/webrtc/video_engine/include/vie_base.h index afddf38adc..f42992f8ef 100644 --- a/webrtc/video_engine/include/vie_base.h +++ b/webrtc/video_engine/include/vie_base.h @@ -25,6 +25,7 @@ namespace webrtc { class Config; class VoiceEngine; +class ReceiveStatisticsProxy; class SendStatisticsProxy; // CpuOveruseObserver is called when a system overuse is detected and @@ -243,6 +244,10 @@ class WEBRTC_DLLEXPORT ViEBase { int channel, SendStatisticsProxy* send_statistics_proxy) = 0; + virtual void RegisterReceiveStatisticsProxy( + int channel, + ReceiveStatisticsProxy* receive_statistics_proxy) = 0; + protected: ViEBase() {} virtual ~ViEBase() {} diff --git a/webrtc/video_engine/vie_base_impl.cc b/webrtc/video_engine/vie_base_impl.cc index 64c96d2322..336d254f52 100644 --- a/webrtc/video_engine/vie_base_impl.cc +++ b/webrtc/video_engine/vie_base_impl.cc @@ -373,4 +373,17 @@ void ViEBaseImpl::RegisterSendStatisticsProxy( vie_encoder->RegisterSendStatisticsProxy(send_statistics_proxy); } + +void ViEBaseImpl::RegisterReceiveStatisticsProxy( + int channel, + ReceiveStatisticsProxy* receive_statistics_proxy) { + LOG_F(LS_VERBOSE) << "RegisterReceiveStatisticsProxy on channel " << channel; + ViEChannelManagerScoped cs(*(shared_data_.channel_manager())); + ViEChannel* vie_channel = cs.Channel(channel); + if (!vie_channel) { + shared_data_.SetLastError(kViEBaseInvalidChannelId); + return; + } + vie_channel->RegisterReceiveStatisticsProxy(receive_statistics_proxy); +} } // namespace webrtc diff --git a/webrtc/video_engine/vie_base_impl.h b/webrtc/video_engine/vie_base_impl.h index f03cd41dfd..c949acd52a 100644 --- a/webrtc/video_engine/vie_base_impl.h +++ b/webrtc/video_engine/vie_base_impl.h @@ -70,6 +70,9 @@ class ViEBaseImpl virtual void RegisterSendStatisticsProxy( int channel, SendStatisticsProxy* send_statistics_proxy) OVERRIDE; + virtual void RegisterReceiveStatisticsProxy( + int channel, + ReceiveStatisticsProxy* receive_statistics_proxy) OVERRIDE; // ViEBaseImpl owns ViESharedData used by all interface implementations. ViESharedData shared_data_; }; diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index 67ec6b8692..ab6453a697 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -16,6 +16,7 @@ #include "webrtc/common.h" #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" #include "webrtc/experiments.h" +#include "webrtc/frame_callback.h" #include "webrtc/modules/pacing/include/paced_sender.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" @@ -27,12 +28,12 @@ #include "webrtc/system_wrappers/interface/logging.h" #include "webrtc/system_wrappers/interface/metrics.h" #include "webrtc/system_wrappers/interface/thread_wrapper.h" +#include "webrtc/video/receive_statistics_proxy.h" #include "webrtc/video_engine/call_stats.h" #include "webrtc/video_engine/include/vie_codec.h" #include "webrtc/video_engine/include/vie_errors.h" #include "webrtc/video_engine/include/vie_image_process.h" #include "webrtc/video_engine/include/vie_rtp_rtcp.h" -#include "webrtc/frame_callback.h" #include "webrtc/video_engine/vie_defines.h" namespace webrtc { @@ -156,6 +157,7 @@ ViEChannel::ViEChannel(int32_t channel_id, rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration)); vie_receiver_.SetRtpRtcpModule(rtp_rtcp_.get()); vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0); + vcm_->RegisterReceiveFrameCountObserver(&receive_frame_count_observer_); } int32_t ViEChannel::Init() { @@ -424,7 +426,7 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec, module_process_thread_.DeRegisterModule(rtp_rtcp); rtp_rtcp->SetSendingStatus(false); rtp_rtcp->SetSendingMediaStatus(false); - rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL); + rtp_rtcp->RegisterRtcpStatisticsCallback(NULL); rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL); simulcast_rtp_rtcp_.pop_back(); removed_rtp_rtcp_.push_front(rtp_rtcp); @@ -471,8 +473,8 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec, rtp_rtcp->DeregisterSendRtpHeaderExtension( kRtpExtensionAbsoluteSendTime); } - rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback( - rtp_rtcp_->GetSendChannelRtcpStatisticsCallback()); + rtp_rtcp->RegisterRtcpStatisticsCallback( + rtp_rtcp_->GetRtcpStatisticsCallback()); rtp_rtcp->RegisterSendChannelRtpStatisticsCallback( rtp_rtcp_->GetSendChannelRtpStatisticsCallback()); } @@ -485,7 +487,7 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec, module_process_thread_.DeRegisterModule(rtp_rtcp); rtp_rtcp->SetSendingStatus(false); rtp_rtcp->SetSendingMediaStatus(false); - rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL); + rtp_rtcp->RegisterRtcpStatisticsCallback(NULL); rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL); simulcast_rtp_rtcp_.pop_back(); removed_rtp_rtcp_.push_front(rtp_rtcp); @@ -577,12 +579,7 @@ int32_t ViEChannel::DeRegisterExternalDecoder(const uint8_t pl_type) { int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames, uint32_t* num_delta_frames) { - VCMFrameCount received_frames; - if (vcm_->ReceivedFrameCount(received_frames) != VCM_OK) { - return -1; - } - *num_key_frames = received_frames.numKeyFrames; - *num_delta_frames = received_frames.numDeltaFrames; + receive_frame_count_observer_.GetFrameCount(num_key_frames, num_delta_frames); return 0; } @@ -1127,12 +1124,12 @@ int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost, void ViEChannel::RegisterSendChannelRtcpStatisticsCallback( RtcpStatisticsCallback* callback) { - rtp_rtcp_->RegisterSendChannelRtcpStatisticsCallback(callback); + rtp_rtcp_->RegisterRtcpStatisticsCallback(callback); CriticalSectionScoped cs(rtp_rtcp_cs_.get()); for (std::list::const_iterator it = simulcast_rtp_rtcp_.begin(); it != simulcast_rtp_rtcp_.end(); ++it) { - (*it)->RegisterSendChannelRtcpStatisticsCallback(callback); + (*it)->RegisterRtcpStatisticsCallback(callback); } } @@ -1168,6 +1165,7 @@ void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback( RtcpStatisticsCallback* callback) { vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback( callback); + rtp_rtcp_->RegisterRtcpStatisticsCallback(callback); } int32_t ViEChannel::GetRtpStatistics(size_t* bytes_sent, @@ -1667,7 +1665,7 @@ void ViEChannel::ReserveRtpRtcpModules(size_t num_modules) { RtpRtcp* rtp_rtcp = CreateRtpRtcpModule(); rtp_rtcp->SetSendingStatus(false); rtp_rtcp->SetSendingMediaStatus(false); - rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL); + rtp_rtcp->RegisterRtcpStatisticsCallback(NULL); rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL); removed_rtp_rtcp_.push_back(rtp_rtcp); } @@ -1848,6 +1846,11 @@ void ViEChannel::RegisterSendFrameCountObserver( send_frame_count_observer_.Set(observer); } +void ViEChannel::RegisterReceiveStatisticsProxy( + ReceiveStatisticsProxy* receive_statistics_proxy) { + receive_frame_count_observer_.Set(receive_statistics_proxy); +} + void ViEChannel::ReceivedBWEPacket(int64_t arrival_time_ms, size_t payload_size, const RTPHeader& header) { diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h index b978353514..dda08eebef 100644 --- a/webrtc/video_engine/vie_channel.h +++ b/webrtc/video_engine/vie_channel.h @@ -39,6 +39,7 @@ class EncodedImageCallback; class I420FrameCallback; class PacedSender; class ProcessThread; +class ReceiveStatisticsProxy; class RtcpRttStats; class ThreadWrapper; class ViEDecoderObserver; @@ -353,7 +354,8 @@ class ViEChannel EncodedImageCallback* pre_decode_callback); void RegisterSendFrameCountObserver(FrameCountObserver* observer); - + void RegisterReceiveStatisticsProxy( + ReceiveStatisticsProxy* receive_statistics_proxy); void ReceivedBWEPacket(int64_t arrival_time_ms, size_t payload_size, const RTPHeader& header); @@ -427,14 +429,24 @@ class ViEChannel class RegisterableFrameCountObserver : public RegisterableCallback { - virtual void FrameCountUpdated(FrameType frame_type, - uint32_t frame_count, - const unsigned int ssrc) { + public: + virtual void FrameCountUpdated(const FrameCounts& frame_counts, + uint32_t ssrc) { CriticalSectionScoped cs(critsect_.get()); + frame_counts_ = frame_counts; if (callback_) - callback_->FrameCountUpdated(frame_type, frame_count, ssrc); + callback_->FrameCountUpdated(frame_counts, ssrc); } - } send_frame_count_observer_; + + void GetFrameCount(uint32_t* num_key_frames, uint32_t* num_delta_frames) { + CriticalSectionScoped cs(critsect_.get()); + *num_key_frames = frame_counts_.key_frames; + *num_delta_frames = frame_counts_.delta_frames; + } + + private: + FrameCounts frame_counts_ GUARDED_BY(critsect_); + } send_frame_count_observer_, receive_frame_count_observer_; class RegisterableSendSideDelayObserver : public RegisterableCallback { diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc index 84b5cdf269..a570922aca 100644 --- a/webrtc/voice_engine/channel.cc +++ b/webrtc/voice_engine/channel.cc @@ -71,6 +71,8 @@ class StatisticsProxy : public RtcpStatisticsCallback { } } + virtual void CNameChanged(const char* cname, uint32_t ssrc) OVERRIDE {} + void ResetStatistics() { CriticalSectionScoped cs(stats_lock_.get()); stats_ = ChannelStatistics();