From 17821db19702aca15d0d93cb60515ca70823fad7 Mon Sep 17 00:00:00 2001 From: asapersson Date: Mon, 14 Dec 2015 02:08:12 -0800 Subject: [PATCH] Wire up bandwidth limitation info to GetStats and adapt_reason. The input resolution (output from video_adapter) can be further scaled down or higher video layer(s) can be dropped due to bitrate constraints. BUG=webrtc:4112 Review URL: https://codereview.webrtc.org/1502173002 Cr-Commit-Position: refs/heads/master@{#11006} --- talk/media/webrtc/webrtcvideoengine2.cc | 8 ++ .../webrtc/webrtcvideoengine2_unittest.cc | 81 +++++++++++++++++++ webrtc/video/send_statistics_proxy.cc | 4 + webrtc/video_send_stream.h | 1 + 4 files changed, 94 insertions(+) diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc index 921e53f316..5deee96bfb 100644 --- a/talk/media/webrtc/webrtcvideoengine2.cc +++ b/talk/media/webrtc/webrtcvideoengine2.cc @@ -2117,6 +2117,14 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { } } } + + // Get bandwidth limitation info from stream_->GetStats(). + // Input resolution (output from video_adapter) can be further scaled down or + // higher video layer(s) can be dropped due to bitrate constraints. + // Note, adapt_changes only include changes from the video_adapter. + if (stats.bw_limited_resolution) + info.adapt_reason |= CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH; + info.ssrc_groups = ssrc_groups_; info.framerate_input = stats.input_frame_rate; info.framerate_sent = stats.encode_frame_rate; diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc index 74eb93e4bf..bd88b9c8da 100644 --- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc +++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc @@ -2553,6 +2553,87 @@ TEST_F(WebRtcVideoChannel2Test, GetStatsTracksAdaptationStats) { EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL)); } +TEST_F(WebRtcVideoChannel2Test, GetStatsTracksAdaptationAndBandwidthStats) { + AddSendStream(cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))); + + // Capture format VGA. + cricket::FakeVideoCapturer video_capturer_vga; + const std::vector* formats = + video_capturer_vga.GetSupportedFormats(); + cricket::VideoFormat capture_format_vga = (*formats)[1]; + EXPECT_EQ(cricket::CS_RUNNING, video_capturer_vga.Start(capture_format_vga)); + EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_vga)); + EXPECT_TRUE(video_capturer_vga.CaptureFrame()); + + cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0); + cricket::VideoSendParameters parameters; + parameters.codecs.push_back(send_codec); + EXPECT_TRUE(channel_->SetSendParameters(parameters)); + EXPECT_TRUE(channel_->SetSend(true)); + + // Verify that the CpuOveruseObserver is registered and trigger downgrade. + parameters.options.cpu_overuse_detection = rtc::Optional(true); + EXPECT_TRUE(channel_->SetSendParameters(parameters)); + + // Trigger overuse -> adapt CPU. + ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size()); + webrtc::LoadObserver* overuse_callback = + fake_call_->GetVideoSendStreams().front()->GetConfig().overuse_callback; + ASSERT_TRUE(overuse_callback != NULL); + overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse); + EXPECT_TRUE(video_capturer_vga.CaptureFrame()); + cricket::VideoMediaInfo info; + EXPECT_TRUE(channel_->GetStats(&info)); + ASSERT_EQ(1U, info.senders.size()); + EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, + info.senders[0].adapt_reason); + + // Set bandwidth limitation stats for the stream -> adapt CPU + BW. + webrtc::VideoSendStream::Stats stats; + stats.bw_limited_resolution = true; + fake_call_->GetVideoSendStreams().front()->SetStats(stats); + info.Clear(); + EXPECT_TRUE(channel_->GetStats(&info)); + ASSERT_EQ(1U, info.senders.size()); + EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU + + CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, + info.senders[0].adapt_reason); + + // Trigger upgrade -> adapt BW. + overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse); + EXPECT_TRUE(video_capturer_vga.CaptureFrame()); + info.Clear(); + EXPECT_TRUE(channel_->GetStats(&info)); + ASSERT_EQ(1U, info.senders.size()); + EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, + info.senders[0].adapt_reason); + + // Reset bandwidth limitation state -> adapt NONE. + stats.bw_limited_resolution = false; + fake_call_->GetVideoSendStreams().front()->SetStats(stats); + info.Clear(); + EXPECT_TRUE(channel_->GetStats(&info)); + ASSERT_EQ(1U, info.senders.size()); + EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_NONE, + info.senders[0].adapt_reason); + + EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL)); +} + +TEST_F(WebRtcVideoChannel2Test, + GetStatsTranslatesBandwidthLimitedResolutionCorrectly) { + FakeVideoSendStream* stream = AddSendStream(); + webrtc::VideoSendStream::Stats stats; + stats.bw_limited_resolution = true; + stream->SetStats(stats); + + cricket::VideoMediaInfo info; + EXPECT_TRUE(channel_->GetStats(&info)); + ASSERT_EQ(1U, info.senders.size()); + EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, + info.senders[0].adapt_reason); +} + TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesSendRtcpPacketTypesCorrectly) { FakeVideoSendStream* stream = AddSendStream(); diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc index 57d38a523b..f5e7e3d024 100644 --- a/webrtc/video/send_statistics_proxy.cc +++ b/webrtc/video/send_statistics_proxy.cc @@ -258,6 +258,10 @@ void SendStatisticsProxy::OnSendEncodedImage( uma_container_->key_frame_counter_.Add(encoded_image._frameType == kVideoFrameKey); + stats_.bw_limited_resolution = + encoded_image.adapt_reason_.quality_resolution_downscales > 0 || + encoded_image.adapt_reason_.bw_resolutions_disabled > 0; + if (encoded_image.adapt_reason_.quality_resolution_downscales != -1) { bool downscaled = encoded_image.adapt_reason_.quality_resolution_downscales > 0; diff --git a/webrtc/video_send_stream.h b/webrtc/video_send_stream.h index d0e0c93a2b..b5f8c9ad1c 100644 --- a/webrtc/video_send_stream.h +++ b/webrtc/video_send_stream.h @@ -69,6 +69,7 @@ class VideoSendStream : public SendStream { int target_media_bitrate_bps = 0; int media_bitrate_bps = 0; bool suspended = false; + bool bw_limited_resolution = false; std::map substreams; };