diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index 3e0df4cd3d..bad2cb496a 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -369,7 +369,6 @@ 'video_coding/jitter_estimator_tests.cc', 'video_coding/media_optimization_unittest.cc', 'video_coding/nack_module_unittest.cc', - 'video_coding/percentile_filter_unittest.cc', 'video_coding/receiver_unittest.cc', 'video_coding/session_info_unittest.cc', 'video_coding/timing_unittest.cc', diff --git a/webrtc/modules/video_coding/BUILD.gn b/webrtc/modules/video_coding/BUILD.gn index 37a0d2cb8f..d95d2bcf7b 100644 --- a/webrtc/modules/video_coding/BUILD.gn +++ b/webrtc/modules/video_coding/BUILD.gn @@ -50,8 +50,6 @@ source_set("video_coding") { "nack_module.h", "packet.cc", "packet.h", - "percentile_filter.cc", - "percentile_filter.h", "qm_select.cc", "qm_select.h", "qm_select_data.h", diff --git a/webrtc/modules/video_coding/codec_timer.cc b/webrtc/modules/video_coding/codec_timer.cc index 0fdf1a692e..60add8fc4b 100644 --- a/webrtc/modules/video_coding/codec_timer.cc +++ b/webrtc/modules/video_coding/codec_timer.cc @@ -10,47 +10,87 @@ #include "webrtc/modules/video_coding/codec_timer.h" +#include + namespace webrtc { -namespace { - // The first kIgnoredSampleCount samples will be ignored. -const int kIgnoredSampleCount = 5; -// Return the |kPercentile| value in RequiredDecodeTimeMs(). -const float kPercentile = 0.95f; -// The window size in ms. -const int64_t kTimeLimitMs = 10000; - -} // anonymous namespace +static const int32_t kIgnoredSampleCount = 5; VCMCodecTimer::VCMCodecTimer() - : ignored_sample_count_(0), filter_(kPercentile) {} + : _filteredMax(0), _ignoredSampleCount(0), _shortMax(0), _history() { + Reset(); +} -void VCMCodecTimer::AddTiming(int64_t decode_time_ms, int64_t now_ms) { - // Ignore the first |kIgnoredSampleCount| samples. - if (ignored_sample_count_ < kIgnoredSampleCount) { - ++ignored_sample_count_; +void VCMCodecTimer::Reset() { + _filteredMax = 0; + _ignoredSampleCount = 0; + _shortMax = 0; + for (int i = 0; i < MAX_HISTORY_SIZE; i++) { + _history[i].shortMax = 0; + _history[i].timeMs = -1; + } +} + +// Update the max-value filter +void VCMCodecTimer::MaxFilter(int32_t decodeTime, int64_t nowMs) { + if (_ignoredSampleCount >= kIgnoredSampleCount) { + UpdateMaxHistory(decodeTime, nowMs); + ProcessHistory(nowMs); + } else { + _ignoredSampleCount++; + } +} + +void VCMCodecTimer::UpdateMaxHistory(int32_t decodeTime, int64_t now) { + if (_history[0].timeMs >= 0 && now - _history[0].timeMs < SHORT_FILTER_MS) { + if (decodeTime > _shortMax) { + _shortMax = decodeTime; + } + } else { + // Only add a new value to the history once a second + if (_history[0].timeMs == -1) { + // First, no shift + _shortMax = decodeTime; + } else { + // Shift + for (int i = (MAX_HISTORY_SIZE - 2); i >= 0; i--) { + _history[i + 1].shortMax = _history[i].shortMax; + _history[i + 1].timeMs = _history[i].timeMs; + } + } + if (_shortMax == 0) { + _shortMax = decodeTime; + } + + _history[0].shortMax = _shortMax; + _history[0].timeMs = now; + _shortMax = 0; + } +} + +void VCMCodecTimer::ProcessHistory(int64_t nowMs) { + _filteredMax = _shortMax; + if (_history[0].timeMs == -1) { return; } - - // Insert new decode time value. - filter_.Insert(decode_time_ms); - history_.emplace(decode_time_ms, now_ms); - - // Pop old decode time values. - while (!history_.empty() && - now_ms - history_.front().sample_time_ms > kTimeLimitMs) { - filter_.Erase(history_.front().decode_time_ms); - history_.pop(); + for (int i = 0; i < MAX_HISTORY_SIZE; i++) { + if (_history[i].timeMs == -1) { + break; + } + if (nowMs - _history[i].timeMs > MAX_HISTORY_SIZE * SHORT_FILTER_MS) { + // This sample (and all samples after this) is too old + break; + } + if (_history[i].shortMax > _filteredMax) { + // This sample is the largest one this far into the history + _filteredMax = _history[i].shortMax; + } } } -// Get the 95th percentile observed decode time within a time window. -int64_t VCMCodecTimer::RequiredDecodeTimeMs() const { - return filter_.GetPercentileValue(); +// Get the maximum observed time within a time window +int32_t VCMCodecTimer::RequiredDecodeTimeMs(FrameType /*frameType*/) const { + return _filteredMax; } - -VCMCodecTimer::Sample::Sample(int64_t decode_time_ms, int64_t sample_time_ms) - : decode_time_ms(decode_time_ms), sample_time_ms(sample_time_ms) {} - } // namespace webrtc diff --git a/webrtc/modules/video_coding/codec_timer.h b/webrtc/modules/video_coding/codec_timer.h index 90ef6bb5e5..8ebd82ab9c 100644 --- a/webrtc/modules/video_coding/codec_timer.h +++ b/webrtc/modules/video_coding/codec_timer.h @@ -11,39 +11,45 @@ #ifndef WEBRTC_MODULES_VIDEO_CODING_CODEC_TIMER_H_ #define WEBRTC_MODULES_VIDEO_CODING_CODEC_TIMER_H_ -#include - #include "webrtc/modules/include/module_common_types.h" -#include "webrtc/modules/video_coding/percentile_filter.h" #include "webrtc/typedefs.h" namespace webrtc { +// MAX_HISTORY_SIZE * SHORT_FILTER_MS defines the window size in milliseconds +#define MAX_HISTORY_SIZE 10 +#define SHORT_FILTER_MS 1000 + +class VCMShortMaxSample { + public: + VCMShortMaxSample() : shortMax(0), timeMs(-1) {} + + int32_t shortMax; + int64_t timeMs; +}; + class VCMCodecTimer { public: VCMCodecTimer(); - // Add a new decode time to the filter. - void AddTiming(int64_t new_decode_time_ms, int64_t now_ms); + // Updates the max filtered decode time. + void MaxFilter(int32_t newDecodeTimeMs, int64_t nowMs); - // Get the required decode time in ms. It is the 95th percentile observed - // decode time within a time window. - int64_t RequiredDecodeTimeMs() const; + // Empty the list of timers. + void Reset(); + + // Get the required decode time in ms. + int32_t RequiredDecodeTimeMs(FrameType frameType) const; private: - struct Sample { - Sample(int64_t decode_time_ms, int64_t sample_time_ms); - int64_t decode_time_ms; - int64_t sample_time_ms; - }; + void UpdateMaxHistory(int32_t decodeTime, int64_t now); + void ProcessHistory(int64_t nowMs); + int32_t _filteredMax; // The number of samples ignored so far. - int ignored_sample_count_; - // Queue with history of latest decode time values. - std::queue history_; - // |filter_| contains the same values as |history_|, but in a data structure - // that allows efficient retrieval of the percentile value. - PercentileFilter filter_; + int32_t _ignoredSampleCount; + int32_t _shortMax; + VCMShortMaxSample _history[MAX_HISTORY_SIZE]; }; } // namespace webrtc diff --git a/webrtc/modules/video_coding/percentile_filter.cc b/webrtc/modules/video_coding/percentile_filter.cc deleted file mode 100644 index 6495567540..0000000000 --- a/webrtc/modules/video_coding/percentile_filter.cc +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/video_coding/percentile_filter.h" - -#include - -#include "webrtc/base/checks.h" - -namespace webrtc { - -PercentileFilter::PercentileFilter(float percentile) - : percentile_(percentile), - percentile_it_(set_.begin()), - percentile_index_(0) { - RTC_CHECK_GE(percentile, 0.0f); - RTC_CHECK_LE(percentile, 1.0f); -} - -void PercentileFilter::Insert(const int64_t& value) { - // Insert element at the upper bound. - set_.insert(value); - if (set_.size() == 1u) { - // First element inserted - initialize percentile iterator and index. - percentile_it_ = set_.begin(); - percentile_index_ = 0; - } else if (value < *percentile_it_) { - // If new element is before us, increment |percentile_index_|. - ++percentile_index_; - } - UpdatePercentileIterator(); -} - -void PercentileFilter::Erase(const int64_t& value) { - std::multiset::const_iterator it = set_.lower_bound(value); - // Ignore erase operation if the element is not present in the current set. - if (it == set_.end() || *it != value) - return; - if (it == percentile_it_) { - // If same iterator, update to the following element. Index is not affected. - percentile_it_ = set_.erase(it); - } else { - set_.erase(it); - // If erased element was before us, decrement |percentile_index_|. - if (value <= *percentile_it_) - --percentile_index_; - } - UpdatePercentileIterator(); -} - -void PercentileFilter::UpdatePercentileIterator() { - if (set_.empty()) - return; - const int64_t index = static_cast(percentile_ * (set_.size() - 1)); - std::advance(percentile_it_, index - percentile_index_); - percentile_index_ = index; -} - -int64_t PercentileFilter::GetPercentileValue() const { - return set_.empty() ? 0 : *percentile_it_; -} - -} // namespace webrtc diff --git a/webrtc/modules/video_coding/percentile_filter.h b/webrtc/modules/video_coding/percentile_filter.h deleted file mode 100644 index 125a244515..0000000000 --- a/webrtc/modules/video_coding/percentile_filter.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_VIDEO_CODING_PERCENTILE_FILTER_H_ -#define WEBRTC_MODULES_VIDEO_CODING_PERCENTILE_FILTER_H_ - -#include - -#include - -namespace webrtc { - -// Class to efficiently get the percentile value from a group of observations. -// The percentile is the value below which a given percentage of the -// observations fall. -class PercentileFilter { - public: - // Construct filter. |percentile| should be between 0 and 1. - explicit PercentileFilter(float percentile); - - // Insert one observation. The complexity of this operation is logarithmic in - // the size of the container. - void Insert(const int64_t& value); - // Remove one observation. The complexity of this operation is logarithmic in - // the size of the container. - void Erase(const int64_t& value); - // Get the percentile value. The complexity of this operation is constant. - int64_t GetPercentileValue() const; - - private: - // Update iterator and index to point at target percentile value. - void UpdatePercentileIterator(); - - const float percentile_; - std::multiset set_; - // Maintain iterator and index of current target percentile value. - std::multiset::iterator percentile_it_; - int64_t percentile_index_; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_VIDEO_CODING_PERCENTILE_FILTER_H_ diff --git a/webrtc/modules/video_coding/percentile_filter_unittest.cc b/webrtc/modules/video_coding/percentile_filter_unittest.cc deleted file mode 100644 index 8029bdbe19..0000000000 --- a/webrtc/modules/video_coding/percentile_filter_unittest.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2016 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/constructormagic.h" -#include "webrtc/modules/video_coding/percentile_filter.h" - -namespace webrtc { - -class PercentileFilterTest : public ::testing::TestWithParam { - public: - PercentileFilterTest() : filter_(GetParam()) { - // Make sure the tests are deterministic by seeding with a constant. - srand(42); - } - - protected: - PercentileFilter filter_; - - private: - RTC_DISALLOW_COPY_AND_ASSIGN(PercentileFilterTest); -}; - -INSTANTIATE_TEST_CASE_P(PercentileFilterTests, - PercentileFilterTest, - ::testing::Values(0.0f, 0.1f, 0.5f, 0.9f, 1.0f)); - -TEST(PercentileFilterTest, MinFilter) { - PercentileFilter filter(0.0f); - filter.Insert(4); - EXPECT_EQ(4, filter.GetPercentileValue()); - filter.Insert(3); - EXPECT_EQ(3, filter.GetPercentileValue()); -} - -TEST(PercentileFilterTest, MaxFilter) { - PercentileFilter filter(1.0f); - filter.Insert(3); - EXPECT_EQ(3, filter.GetPercentileValue()); - filter.Insert(4); - EXPECT_EQ(4, filter.GetPercentileValue()); -} - -TEST_P(PercentileFilterTest, EmptyFilter) { - EXPECT_EQ(0, filter_.GetPercentileValue()); - filter_.Insert(3); - filter_.Erase(3); - EXPECT_EQ(0, filter_.GetPercentileValue()); -} - -TEST_P(PercentileFilterTest, EraseNonExistingElement) { - filter_.Erase(3); - EXPECT_EQ(0, filter_.GetPercentileValue()); - filter_.Insert(4); - filter_.Erase(3); - EXPECT_EQ(4, filter_.GetPercentileValue()); -} - -TEST_P(PercentileFilterTest, DuplicateElements) { - filter_.Insert(3); - filter_.Insert(3); - filter_.Erase(3); - EXPECT_EQ(3, filter_.GetPercentileValue()); -} - -TEST_P(PercentileFilterTest, InsertAndEraseTenValuesInRandomOrder) { - int64_t zero_to_nine[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - // The percentile value of the ten values above. - const int64_t expected_value = static_cast(GetParam() * 9); - - // Insert two sets of |zero_to_nine| in random order. - for (int i = 0; i < 2; ++i) { - std::random_shuffle(zero_to_nine, zero_to_nine + 10); - for (int64_t value : zero_to_nine) - filter_.Insert(value); - // After inserting a full set of |zero_to_nine|, the percentile should - // stay constant. - EXPECT_EQ(expected_value, filter_.GetPercentileValue()); - } - - // Insert and erase sets of |zero_to_nine| in random order a few times. - for (int i = 0; i < 3; ++i) { - std::random_shuffle(zero_to_nine, zero_to_nine + 10); - for (int64_t value : zero_to_nine) - filter_.Erase(value); - EXPECT_EQ(expected_value, filter_.GetPercentileValue()); - - std::random_shuffle(zero_to_nine, zero_to_nine + 10); - for (int64_t value : zero_to_nine) - filter_.Insert(value); - EXPECT_EQ(expected_value, filter_.GetPercentileValue()); - } -} - -} // namespace webrtc diff --git a/webrtc/modules/video_coding/timing.cc b/webrtc/modules/video_coding/timing.cc index 91f5f8423c..680860a191 100644 --- a/webrtc/modules/video_coding/timing.cc +++ b/webrtc/modules/video_coding/timing.cc @@ -25,7 +25,7 @@ VCMTiming::VCMTiming(Clock* clock, VCMTiming* master_timing) clock_(clock), master_(false), ts_extrapolator_(), - codec_timer_(new VCMCodecTimer()), + codec_timer_(), render_delay_ms_(kDefaultRenderDelayMs), min_playout_delay_ms_(0), jitter_delay_ms_(0), @@ -78,7 +78,7 @@ void VCMTiming::UpdateHistograms() const { void VCMTiming::Reset() { CriticalSectionScoped cs(crit_sect_); ts_extrapolator_->Reset(clock_->TimeInMilliseconds()); - codec_timer_.reset(new VCMCodecTimer()); + codec_timer_.Reset(); render_delay_ms_ = kDefaultRenderDelayMs; min_playout_delay_ms_ = 0; jitter_delay_ms_ = 0; @@ -88,7 +88,7 @@ void VCMTiming::Reset() { void VCMTiming::ResetDecodeTime() { CriticalSectionScoped lock(crit_sect_); - codec_timer_.reset(new VCMCodecTimer()); + codec_timer_.Reset(); } void VCMTiming::set_render_delay(uint32_t render_delay_ms) { @@ -156,9 +156,8 @@ void VCMTiming::UpdateCurrentDelay(int64_t render_time_ms, int64_t actual_decode_time_ms) { CriticalSectionScoped cs(crit_sect_); uint32_t target_delay_ms = TargetDelayInternal(); - int64_t delayed_ms = - actual_decode_time_ms - - (render_time_ms - RequiredDecodeTimeMs() - render_delay_ms_); + int64_t delayed_ms = actual_decode_time_ms - + (render_time_ms - MaxDecodeTimeMs() - render_delay_ms_); if (delayed_ms < 0) { return; } @@ -174,7 +173,7 @@ int32_t VCMTiming::StopDecodeTimer(uint32_t time_stamp, int64_t now_ms, int64_t render_time_ms) { CriticalSectionScoped cs(crit_sect_); - codec_timer_->AddTiming(decode_time_ms, now_ms); + codec_timer_.MaxFilter(decode_time_ms, now_ms); assert(decode_time_ms >= 0); last_decode_ms_ = decode_time_ms; @@ -217,8 +216,9 @@ int64_t VCMTiming::RenderTimeMsInternal(uint32_t frame_timestamp, } // Must be called from inside a critical section. -int64_t VCMTiming::RequiredDecodeTimeMs() const { - const int64_t decode_time_ms = codec_timer_->RequiredDecodeTimeMs(); +int32_t VCMTiming::MaxDecodeTimeMs( + FrameType frame_type /*= kVideoFrameDelta*/) const { + const int32_t decode_time_ms = codec_timer_.RequiredDecodeTimeMs(frame_type); assert(decode_time_ms >= 0); return decode_time_ms; } @@ -228,7 +228,7 @@ uint32_t VCMTiming::MaxWaitingTime(int64_t render_time_ms, CriticalSectionScoped cs(crit_sect_); const int64_t max_wait_time_ms = - render_time_ms - now_ms - RequiredDecodeTimeMs() - render_delay_ms_; + render_time_ms - now_ms - MaxDecodeTimeMs() - render_delay_ms_; if (max_wait_time_ms < 0) { return 0; @@ -239,18 +239,18 @@ uint32_t VCMTiming::MaxWaitingTime(int64_t render_time_ms, bool VCMTiming::EnoughTimeToDecode( uint32_t available_processing_time_ms) const { CriticalSectionScoped cs(crit_sect_); - int64_t required_decode_time_ms = RequiredDecodeTimeMs(); - if (required_decode_time_ms < 0) { + int32_t max_decode_time_ms = MaxDecodeTimeMs(); + if (max_decode_time_ms < 0) { // Haven't decoded any frames yet, try decoding one to get an estimate // of the decode time. return true; - } else if (required_decode_time_ms == 0) { + } else if (max_decode_time_ms == 0) { // Decode time is less than 1, set to 1 for now since // we don't have any better precision. Count ticks later? - required_decode_time_ms = 1; + max_decode_time_ms = 1; } - return static_cast(available_processing_time_ms) - - required_decode_time_ms > + return static_cast(available_processing_time_ms) - + max_decode_time_ms > 0; } @@ -261,9 +261,7 @@ uint32_t VCMTiming::TargetVideoDelay() const { uint32_t VCMTiming::TargetDelayInternal() const { return std::max(min_playout_delay_ms_, - jitter_delay_ms_ + - static_cast(RequiredDecodeTimeMs()) + - render_delay_ms_); + jitter_delay_ms_ + MaxDecodeTimeMs() + render_delay_ms_); } void VCMTiming::GetTimings(int* decode_ms, @@ -275,7 +273,7 @@ void VCMTiming::GetTimings(int* decode_ms, int* render_delay_ms) const { CriticalSectionScoped cs(crit_sect_); *decode_ms = last_decode_ms_; - *max_decode_ms = static_cast(RequiredDecodeTimeMs()); + *max_decode_ms = MaxDecodeTimeMs(); *current_delay_ms = current_delay_ms_; *target_delay_ms = TargetDelayInternal(); *jitter_buffer_ms = jitter_delay_ms_; diff --git a/webrtc/modules/video_coding/timing.h b/webrtc/modules/video_coding/timing.h index a45eee38c6..a4d0cf4543 100644 --- a/webrtc/modules/video_coding/timing.h +++ b/webrtc/modules/video_coding/timing.h @@ -11,8 +11,6 @@ #ifndef WEBRTC_MODULES_VIDEO_CODING_TIMING_H_ #define WEBRTC_MODULES_VIDEO_CODING_TIMING_H_ -#include - #include "webrtc/base/thread_annotations.h" #include "webrtc/modules/video_coding/codec_timer.h" #include "webrtc/system_wrappers/include/critical_section_wrapper.h" @@ -96,7 +94,7 @@ class VCMTiming { enum { kDelayMaxChangeMsPerS = 100 }; protected: - int64_t RequiredDecodeTimeMs() const + int32_t MaxDecodeTimeMs(FrameType frame_type = kVideoFrameDelta) const EXCLUSIVE_LOCKS_REQUIRED(crit_sect_); int64_t RenderTimeMsInternal(uint32_t frame_timestamp, int64_t now_ms) const EXCLUSIVE_LOCKS_REQUIRED(crit_sect_); @@ -109,7 +107,7 @@ class VCMTiming { Clock* const clock_; bool master_ GUARDED_BY(crit_sect_); TimestampExtrapolator* ts_extrapolator_ GUARDED_BY(crit_sect_); - std::unique_ptr codec_timer_ GUARDED_BY(crit_sect_); + VCMCodecTimer codec_timer_ GUARDED_BY(crit_sect_); uint32_t render_delay_ms_ GUARDED_BY(crit_sect_); uint32_t min_playout_delay_ms_ GUARDED_BY(crit_sect_); uint32_t jitter_delay_ms_ GUARDED_BY(crit_sect_); diff --git a/webrtc/modules/video_coding/timing_unittest.cc b/webrtc/modules/video_coding/timing_unittest.cc index 51ef354ec0..2e8df83683 100644 --- a/webrtc/modules/video_coding/timing_unittest.cc +++ b/webrtc/modules/video_coding/timing_unittest.cc @@ -29,7 +29,7 @@ TEST(ReceiverTiming, Tests) { VCMTiming timing(&clock); uint32_t waitTime = 0; uint32_t jitterDelayMs = 0; - uint32_t requiredDecodeTimeMs = 0; + uint32_t maxDecodeTimeMs = 0; uint32_t timeStamp = 0; timing.Reset(); @@ -94,7 +94,7 @@ TEST(ReceiverTiming, Tests) { clock.AdvanceTimeMilliseconds(1000 / 25 - 10); timing.IncomingTimestamp(timeStamp, clock.TimeInMilliseconds()); } - requiredDecodeTimeMs = 10; + maxDecodeTimeMs = 10; timing.SetJitterDelay(jitterDelayMs); clock.AdvanceTimeMilliseconds(1000); timeStamp += 90000; @@ -116,7 +116,7 @@ TEST(ReceiverTiming, Tests) { clock.TimeInMilliseconds()); // We should at least have minTotalDelayMs - decodeTime (10) - renderTime // (10) to wait. - EXPECT_EQ(waitTime, minTotalDelayMs - requiredDecodeTimeMs - kRenderDelayMs); + EXPECT_EQ(waitTime, minTotalDelayMs - maxDecodeTimeMs - kRenderDelayMs); // The total video delay should be equal to the min total delay. EXPECT_EQ(minTotalDelayMs, timing.TargetVideoDelay()); diff --git a/webrtc/modules/video_coding/video_coding.gypi b/webrtc/modules/video_coding/video_coding.gypi index 82c272654c..02c9c6b32b 100644 --- a/webrtc/modules/video_coding/video_coding.gypi +++ b/webrtc/modules/video_coding/video_coding.gypi @@ -47,7 +47,6 @@ 'nack_fec_tables.h', 'nack_module.h', 'packet.h', - 'percentile_filter.h', 'qm_select_data.h', 'qm_select.h', 'receiver.h', @@ -75,7 +74,6 @@ 'media_optimization.cc', 'nack_module.cc', 'packet.cc', - 'percentile_filter.cc', 'qm_select.cc', 'receiver.cc', 'rtt_filter.cc',