From e6f84ae8a602ce78733d20b280ce32198e7ecef5 Mon Sep 17 00:00:00 2001 From: "pbos@webrtc.org" Date: Fri, 18 Jul 2014 11:11:55 +0000 Subject: [PATCH] Initial WebRtcVideoEngine2::GetStats(). Also forward-declaring and moving WebRtcVideoRenderer out of header. BUG=1788 R=pthatcher@webrtc.org, wu@webrtc.org Review URL: https://webrtc-codereview.appspot.com/13869004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6729 4adac7df-926f-26a2-2b94-8c16560cd09d --- talk/media/webrtc/webrtcvideoengine2.cc | 107 +++++++++++++++++- talk/media/webrtc/webrtcvideoengine2.h | 13 ++- .../webrtc/webrtcvideoengine2_unittest.cc | 8 +- 3 files changed, 118 insertions(+), 10 deletions(-) diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc index 03c5e145f..1ce1b99dc 100644 --- a/talk/media/webrtc/webrtcvideoengine2.cc +++ b/talk/media/webrtc/webrtcvideoengine2.cc @@ -638,8 +638,6 @@ class WebRtcVideoRenderFrame : public VideoFrame { const webrtc::I420VideoFrame* const frame_; }; -// WebRtcVideoChannel2 - WebRtcVideoChannel2::WebRtcVideoChannel2( WebRtcVideoEngine2* engine, VoiceMediaChannel* voice_channel, @@ -1048,10 +1046,36 @@ bool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { bool WebRtcVideoChannel2::GetStats(const StatsOptions& options, VideoMediaInfo* info) { - // TODO(pbos): Implement. + info->Clear(); + FillSenderStats(info); + FillReceiverStats(info); + FillBandwidthEstimationStats(info); return true; } +void WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { + for (std::map::iterator it = + send_streams_.begin(); + it != send_streams_.end(); + ++it) { + video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); + } +} + +void WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { + for (std::map::iterator it = + receive_streams_.begin(); + it != receive_streams_.end(); + ++it) { + video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); + } +} + +void WebRtcVideoChannel2::FillBandwidthEstimationStats( + VideoMediaInfo* video_media_info) { + // TODO(pbos): Implement. +} + bool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " << (capturer != NULL ? "(capturer)" : "NULL"); @@ -1549,6 +1573,60 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { sending_ = false; } +VideoSenderInfo +WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { + VideoSenderInfo info; + talk_base::CritScope cs(&lock_); + for (size_t i = 0; i < parameters_.config.rtp.ssrcs.size(); ++i) { + info.add_ssrc(parameters_.config.rtp.ssrcs[i]); + } + + webrtc::VideoSendStream::Stats stats = stream_->GetStats(); + info.framerate_input = stats.input_frame_rate; + info.framerate_sent = stats.encode_frame_rate; + + for (std::map::iterator it = + stats.substreams.begin(); + it != stats.substreams.end(); + ++it) { + // TODO(pbos): Wire up additional stats, such as padding bytes. + webrtc::StreamStats stream_stats = it->second; + info.bytes_sent += stream_stats.rtp_stats.bytes + + stream_stats.rtp_stats.header_bytes + + stream_stats.rtp_stats.padding_bytes; + info.packets_sent += stream_stats.rtp_stats.packets; + info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; + } + + if (!stats.substreams.empty()) { + // TODO(pbos): Report fraction lost per SSRC. + webrtc::StreamStats first_stream_stats = stats.substreams.begin()->second; + info.fraction_lost = + static_cast(first_stream_stats.rtcp_stats.fraction_lost) / + (1 << 8); + } + + if (capturer_ != NULL && !capturer_->IsMuted()) { + VideoFormat last_captured_frame_format; + capturer_->GetStats(&info.adapt_frame_drops, + &info.effects_frame_drops, + &info.capturer_frame_time, + &last_captured_frame_format); + info.input_frame_width = last_captured_frame_format.width; + info.input_frame_height = last_captured_frame_format.height; + info.send_frame_width = + static_cast(parameters_.video_streams.front().width); + info.send_frame_height = + static_cast(parameters_.video_streams.front().height); + } + + // TODO(pbos): Support or remove the following stats. + info.packets_cached = -1; + info.rtt_ms = -1; + + return info; +} + void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { if (stream_ != NULL) { call_->DestroyVideoSendStream(stream_); @@ -1671,6 +1749,29 @@ void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, last_height_ = height; } +VideoReceiverInfo +WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { + VideoReceiverInfo info; + info.add_ssrc(config_.rtp.remote_ssrc); + webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); + info.bytes_rcvd = stats.rtp_stats.bytes + stats.rtp_stats.header_bytes + + stats.rtp_stats.padding_bytes; + info.packets_rcvd = stats.rtp_stats.packets; + + info.framerate_rcvd = stats.network_frame_rate; + info.framerate_decoded = stats.decode_frame_rate; + info.framerate_output = stats.render_frame_rate; + + talk_base::CritScope frame_cs(&renderer_lock_); + info.frame_width = last_width_; + info.frame_height = last_height_; + + // TODO(pbos): Support or remove the following stats. + info.packets_concealed = -1; + + return info; +} + WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() : rtx_payload_type(-1) {} diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h index fe798b50c..e93f57145 100644 --- a/talk/media/webrtc/webrtcvideoengine2.h +++ b/talk/media/webrtc/webrtcvideoengine2.h @@ -80,6 +80,7 @@ struct Device; class WebRtcVideoEngine2; class WebRtcVideoChannel2; +class WebRtcVideoRenderer; class WebRtcVideoEncoderFactory2 { public: @@ -277,6 +278,8 @@ class WebRtcVideoChannel2 : public talk_base::MessageHandler, void Start(); void Stop(); + VideoSenderInfo GetVideoSenderInfo(); + private: // Parameters needed to reconstruct the underlying stream. // webrtc::VideoSendStream doesn't support setting a lot of options on the @@ -337,6 +340,8 @@ class WebRtcVideoChannel2 : public talk_base::MessageHandler, void SetRenderer(cricket::VideoRenderer* renderer); cricket::VideoRenderer* GetRenderer(); + VideoReceiverInfo GetVideoReceiverInfo(); + private: void SetSize(int width, int height); void RecreateWebRtcStream(); @@ -348,8 +353,8 @@ class WebRtcVideoChannel2 : public talk_base::MessageHandler, talk_base::CriticalSection renderer_lock_; cricket::VideoRenderer* renderer_ GUARDED_BY(renderer_lock_); - int last_width_; - int last_height_; + int last_width_ GUARDED_BY(renderer_lock_); + int last_height_ GUARDED_BY(renderer_lock_); }; void Construct(webrtc::Call* call, WebRtcVideoEngine2* engine); @@ -365,6 +370,10 @@ class WebRtcVideoChannel2 : public talk_base::MessageHandler, std::vector FilterSupportedCodecs( const std::vector& mapped_codecs); + void FillSenderStats(VideoMediaInfo* info); + void FillReceiverStats(VideoMediaInfo* info); + void FillBandwidthEstimationStats(VideoMediaInfo* info); + uint32_t rtcp_receiver_report_ssrc_; bool sending_; talk_base::scoped_ptr call_; diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc index d272929e4..0954bcb95 100644 --- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc +++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc @@ -451,15 +451,13 @@ TEST_F(WebRtcVideoChannel2BaseTest, SetSendSetsTransportBufferSizes) { Base::SetSendSetsTransportBufferSizes(); } -// TODO(juberti): Fix this test to tolerate missing stats. -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_GetStats) { Base::GetStats(); } +TEST_F(WebRtcVideoChannel2BaseTest, GetStats) { Base::GetStats(); } -// TODO(juberti): Fix this test to tolerate missing stats. -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_GetStatsMultipleRecvStreams) { +TEST_F(WebRtcVideoChannel2BaseTest, GetStatsMultipleRecvStreams) { Base::GetStatsMultipleRecvStreams(); } -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_GetStatsMultipleSendStreams) { +TEST_F(WebRtcVideoChannel2BaseTest, GetStatsMultipleSendStreams) { Base::GetStatsMultipleSendStreams(); }