From 8d564722d7c3af1948c345175675106a75b75d3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85sa=20Persson?= Date: Tue, 3 Aug 2021 14:43:01 +0200 Subject: [PATCH] Fix for encoded framerate stats per layer. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update framerate for top spatial layer instead of per timestamp (to ensure all simulcast layers are updated). Bug: webrtc:13037 Change-Id: I4fa423dee40d74aee22a87855207b885f0536e25 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/227344 Commit-Queue: Åsa Persson Reviewed-by: Erik Språng Cr-Commit-Position: refs/heads/master@{#34634} --- video/send_statistics_proxy.cc | 6 ++- video/send_statistics_proxy_unittest.cc | 51 +++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/video/send_statistics_proxy.cc b/video/send_statistics_proxy.cc index 8a6712b327..d3e8774970 100644 --- a/video/send_statistics_proxy.cc +++ b/video/send_statistics_proxy.cc @@ -1019,9 +1019,13 @@ void SendStatisticsProxy::OnSendEncodedImage( media_byte_rate_tracker_.AddSamples(encoded_image.size()); if (uma_container_->InsertEncodedFrame(encoded_image, simulcast_idx)) { - encoded_frame_rate_trackers_[simulcast_idx]->AddSamples(1); + // First frame seen with this timestamp, track overall fps. encoded_frame_rate_tracker_.AddSamples(1); } + // is_top_spatial_layer pertains only to SVC, will always be true for + // simulcast. + if (is_top_spatial_layer) + encoded_frame_rate_trackers_[simulcast_idx]->AddSamples(1); absl::optional downscales = adaptation_limitations_.MaskedQualityCounts().resolution_adaptations; diff --git a/video/send_statistics_proxy_unittest.cc b/video/send_statistics_proxy_unittest.cc index cfb190517d..01dbebdbd9 100644 --- a/video/send_statistics_proxy_unittest.cc +++ b/video/send_statistics_proxy_unittest.cc @@ -477,6 +477,57 @@ TEST_F(SendStatisticsProxyTest, EncodeFrameRateInSubStream) { EXPECT_EQ(stats.substreams[ssrc].encode_frame_rate, 10); } +TEST_F(SendStatisticsProxyTest, EncodeFrameRateInSubStreamsVp8Simulcast) { + const int kInterframeDelayMs = 100; + rtc::ScopedFakeClock fake_global_clock; + EncodedImage encoded_image; + CodecSpecificInfo codec_info; + codec_info.codecType = kVideoCodecVP8; + + for (int i = 0; i < 10; ++i) { + fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs); + fake_global_clock.SetTime( + Timestamp::Millis(fake_clock_.TimeInMilliseconds())); + encoded_image.SetTimestamp(encoded_image.Timestamp() + + 90 * kInterframeDelayMs); + encoded_image.SetSpatialIndex(0); + statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); + encoded_image.SetSpatialIndex(1); + statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); + } + + VideoSendStream::Stats stats = statistics_proxy_->GetStats(); + EXPECT_EQ(2u, stats.substreams.size()); + EXPECT_EQ(stats.substreams[config_.rtp.ssrcs[0]].encode_frame_rate, 10); + EXPECT_EQ(stats.substreams[config_.rtp.ssrcs[1]].encode_frame_rate, 10); +} + +TEST_F(SendStatisticsProxyTest, EncodeFrameRateInSubStreamsVp9Svc) { + const int kInterframeDelayMs = 100; + rtc::ScopedFakeClock fake_global_clock; + EncodedImage encoded_image; + CodecSpecificInfo codec_info; + codec_info.codecType = kVideoCodecVP9; + + for (int i = 0; i < 10; ++i) { + fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs); + fake_global_clock.SetTime( + Timestamp::Millis(fake_clock_.TimeInMilliseconds())); + encoded_image.SetTimestamp(encoded_image.Timestamp() + + 90 * kInterframeDelayMs); + encoded_image.SetSpatialIndex(0); + codec_info.end_of_picture = false; + statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); + encoded_image.SetSpatialIndex(1); + codec_info.end_of_picture = true; + statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); + } + + VideoSendStream::Stats stats = statistics_proxy_->GetStats(); + EXPECT_EQ(1u, stats.substreams.size()); + EXPECT_EQ(stats.substreams[config_.rtp.ssrcs[0]].encode_frame_rate, 10); +} + TEST_F(SendStatisticsProxyTest, GetCpuAdaptationStats) { VideoAdaptationCounters cpu_counts; VideoAdaptationCounters quality_counts;