From 20317f9ca48fa3376e5356bf3e951d61da7a14f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85sa=20Persson?= Date: Wed, 15 Aug 2018 08:57:54 +0200 Subject: [PATCH] Clear encoded frame map on gap in timestamp. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep a small window in order to distinguish old and new timestamp. Bug: chromium:816819 Change-Id: Iefa694c744e8e4b19d3857c567162cdc9410b4da Reviewed-on: https://webrtc-review.googlesource.com/94141 Commit-Queue: Åsa Persson Reviewed-by: Erik Språng Reviewed-by: Yves Gerey Cr-Commit-Position: refs/heads/master@{#24285} --- video/send_statistics_proxy.cc | 17 +++++++++++++++++ video/send_statistics_proxy_unittest.cc | 8 ++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/video/send_statistics_proxy.cc b/video/send_statistics_proxy.cc index dac3c03dad..2fb955c3dc 100644 --- a/video/send_statistics_proxy.cc +++ b/video/send_statistics_proxy.cc @@ -12,12 +12,14 @@ #include #include +#include #include #include "common_types.h" // NOLINT(build/include) #include "modules/video_coding/include/video_codec_interface.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" +#include "rtc_base/numerics/mod_ops.h" #include "rtc_base/strings/string_builder.h" #include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/metrics.h" @@ -27,6 +29,7 @@ namespace { const float kEncodeTimeWeigthFactor = 0.5f; const size_t kMaxEncodedFrameMapSize = 150; const int64_t kMaxEncodedFrameWindowMs = 800; +const uint32_t kMaxEncodedFrameTimestampDiff = 900000; // 10 sec. const int64_t kBucketSizeMs = 100; const size_t kBucketCount = 10; @@ -173,6 +176,9 @@ SendStatisticsProxy::UmaSamplesContainer::UmaSamplesContainer( num_streams_(0), num_pixels_highest_stream_(0) { InitializeBitrateCounters(stats); + static_assert( + kMaxEncodedFrameTimestampDiff < std::numeric_limits::max() / 2, + "has to be smaller than half range"); } SendStatisticsProxy::UmaSamplesContainer::~UmaSamplesContainer() {} @@ -241,6 +247,17 @@ bool SendStatisticsProxy::UmaSamplesContainer::InsertEncodedFrame( encoded_frames_.clear(); } + // Check for jump in timestamp. + if (!encoded_frames_.empty()) { + uint32_t oldest_timestamp = encoded_frames_.begin()->first; + if (ForwardDiff(oldest_timestamp, encoded_frame._timeStamp) > + kMaxEncodedFrameTimestampDiff) { + // Gap detected, clear frames to have a sequence where newest timestamp + // is not too far away from oldest in order to distinguish old and new. + encoded_frames_.clear(); + } + } + auto it = encoded_frames_.find(encoded_frame._timeStamp); if (it == encoded_frames_.end()) { // First frame with this timestamp. diff --git a/video/send_statistics_proxy_unittest.cc b/video/send_statistics_proxy_unittest.cc index f4e2fe7486..6942e36b5d 100644 --- a/video/send_statistics_proxy_unittest.cc +++ b/video/send_statistics_proxy_unittest.cc @@ -1027,7 +1027,7 @@ TEST_F(SendStatisticsProxyTest, InputResolutionHistogramsAreUpdated) { TEST_F(SendStatisticsProxyTest, SentResolutionHistogramsAreUpdated) { const int64_t kMaxEncodedFrameWindowMs = 800; - const int kFps = 20; + const int kFps = 5; const int kNumFramesPerWindow = kFps * kMaxEncodedFrameWindowMs / 1000; const int kMinSamples = // Sample added when removed from EncodedFrameMap. SendStatisticsProxy::kMinRequiredMetricsSamples + kNumFramesPerWindow; @@ -1036,7 +1036,7 @@ TEST_F(SendStatisticsProxyTest, SentResolutionHistogramsAreUpdated) { // Not enough samples, stats should not be updated. for (int i = 0; i < kMinSamples - 1; ++i) { fake_clock_.AdvanceTimeMilliseconds(1000 / kFps); - ++encoded_image._timeStamp; + encoded_image._timeStamp += 90 * 1000 / kFps; statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr); } SetUp(); // Reset stats proxy also causes histograms to be reported. @@ -1044,10 +1044,10 @@ TEST_F(SendStatisticsProxyTest, SentResolutionHistogramsAreUpdated) { EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.SentHeightInPixels")); // Enough samples, max resolution per frame should be reported. - encoded_image._timeStamp = 0xfffffff0; // Will wrap. + encoded_image._timeStamp = 0xffff0000; // Will wrap. for (int i = 0; i < kMinSamples; ++i) { fake_clock_.AdvanceTimeMilliseconds(1000 / kFps); - ++encoded_image._timeStamp; + encoded_image._timeStamp += 90 * 1000 / kFps; encoded_image._encodedWidth = kWidth; encoded_image._encodedHeight = kHeight; statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);