| Index: webrtc/modules/video_coding/utility/quality_scaler_unittest.cc
|
| diff --git a/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc b/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc
|
| index 24d5c48d38a3fe2b6424832a99daee1c0c041f65..babe14e002e43d46a84ead63f58562d14b1e9a0a 100644
|
| --- a/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc
|
| +++ b/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc
|
| @@ -10,28 +10,49 @@
|
|
|
| #include "webrtc/modules/video_coding/utility/quality_scaler.h"
|
|
|
| +#include <memory>
|
| +
|
| +#include "webrtc/base/event.h"
|
| +#include "webrtc/base/task_queue.h"
|
| +#include "webrtc/test/gmock.h"
|
| #include "webrtc/test/gtest.h"
|
|
|
| namespace webrtc {
|
| namespace {
|
| -static const int kNumSeconds = 10;
|
| -static const int kWidth = 1920;
|
| -static const int kHeight = 1080;
|
| static const int kFramerate = 30;
|
| static const int kLowQp = 15;
|
| -static const int kNormalQp = 30;
|
| static const int kLowQpThreshold = 18;
|
| static const int kHighQp = 40;
|
| -static const int kDisabledBadQpThreshold = 64;
|
| -static const int kLowInitialBitrateKbps = 300;
|
| -// These values need to be in sync with corresponding constants
|
| -// in quality_scaler.cc
|
| -static const int kMeasureSecondsFastUpscale = 2;
|
| -static const int kMeasureSecondsUpscale = 5;
|
| -static const int kMeasureSecondsDownscale = 5;
|
| -static const int kMinDownscaleDimension = 140;
|
| +static const size_t kDefaultTimeoutMs = 1000;
|
| } // namespace
|
|
|
| +class MockScaleObserver : public ScalingObserverInterface {
|
| + public:
|
| + MockScaleObserver() : event(false, false) {}
|
| + virtual ~MockScaleObserver() {}
|
| +
|
| + void ScaleUp(ScaleReason r) override {
|
| + scaled_up++;
|
| + event.Set();
|
| + }
|
| + void ScaleDown(ScaleReason r) override {
|
| + scaled_down++;
|
| + event.Set();
|
| + }
|
| +
|
| + rtc::Event event;
|
| + int scaled_up = 0;
|
| + int scaled_down = 0;
|
| +};
|
| +
|
| +// Pass a lower sampling period to speed up the tests.
|
| +class QualityScalerUnderTest : public QualityScaler {
|
| + public:
|
| + explicit QualityScalerUnderTest(ScalingObserverInterface* observer,
|
| + VideoEncoder::QpThresholds thresholds)
|
| + : QualityScaler(observer, thresholds, 5) {}
|
| +};
|
| +
|
| class QualityScalerTest : public ::testing::Test {
|
| protected:
|
| enum ScaleDirection {
|
| @@ -41,346 +62,116 @@ class QualityScalerTest : public ::testing::Test {
|
| kScaleUp
|
| };
|
|
|
| - QualityScalerTest() {
|
| - input_frame_ = I420Buffer::Create(kWidth, kHeight);
|
| - qs_.Init(kLowQpThreshold, kHighQp, 0, kWidth, kHeight, kFramerate);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| + QualityScalerTest()
|
| + : q_(new rtc::TaskQueue("QualityScalerTestQueue")),
|
| + observer_(new MockScaleObserver()) {
|
| + rtc::Event event(false, false);
|
| + q_->PostTask([this, &event] {
|
| + qs_ = std::unique_ptr<QualityScaler>(new QualityScalerUnderTest(
|
| + observer_.get(),
|
| + VideoEncoder::QpThresholds(kLowQpThreshold, kHighQp)));
|
| + event.Set();
|
| + });
|
| + EXPECT_TRUE(event.Wait(kDefaultTimeoutMs));
|
| + }
|
| +
|
| + ~QualityScalerTest() {
|
| + rtc::Event event(false, false);
|
| + q_->PostTask([this, &event] {
|
| + qs_.reset(nullptr);
|
| + event.Set();
|
| + });
|
| + EXPECT_TRUE(event.Wait(kDefaultTimeoutMs));
|
| }
|
|
|
| - bool TriggerScale(ScaleDirection scale_direction) {
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - int initial_width = qs_.GetScaledResolution().width;
|
| - for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
|
| + void TriggerScale(ScaleDirection scale_direction) {
|
| + for (int i = 0; i < kFramerate * 5; ++i) {
|
| switch (scale_direction) {
|
| case kScaleUp:
|
| - qs_.ReportQP(kLowQp);
|
| + qs_->ReportQP(kLowQp);
|
| break;
|
| case kScaleDown:
|
| - qs_.ReportDroppedFrame();
|
| + qs_->ReportDroppedFrame();
|
| break;
|
| case kKeepScaleAtHighQp:
|
| - qs_.ReportQP(kHighQp);
|
| + qs_->ReportQP(kHighQp);
|
| break;
|
| case kScaleDownAboveHighQp:
|
| - qs_.ReportQP(kHighQp + 1);
|
| + qs_->ReportQP(kHighQp + 1);
|
| break;
|
| }
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - if (qs_.GetScaledResolution().width != initial_width)
|
| - return true;
|
| }
|
| -
|
| - return false;
|
| - }
|
| -
|
| - void ExpectOriginalFrame() {
|
| - EXPECT_EQ(input_frame_, qs_.GetScaledBuffer(input_frame_))
|
| - << "Using scaled frame instead of original input.";
|
| - }
|
| -
|
| - void ExpectScaleUsingReportedResolution() {
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - QualityScaler::Resolution res = qs_.GetScaledResolution();
|
| - rtc::scoped_refptr<VideoFrameBuffer> scaled_frame =
|
| - qs_.GetScaledBuffer(input_frame_);
|
| - EXPECT_EQ(res.width, scaled_frame->width());
|
| - EXPECT_EQ(res.height, scaled_frame->height());
|
| }
|
|
|
| - void ContinuouslyDownscalesByHalfDimensionsAndBackUp();
|
| -
|
| - void DoesNotDownscaleFrameDimensions(int width, int height);
|
| -
|
| - void DownscaleEndsAt(int input_width,
|
| - int input_height,
|
| - int end_width,
|
| - int end_height);
|
| -
|
| - QualityScaler qs_;
|
| - rtc::scoped_refptr<VideoFrameBuffer> input_frame_;
|
| + std::unique_ptr<rtc::TaskQueue> q_;
|
| + std::unique_ptr<QualityScaler> qs_;
|
| + std::unique_ptr<MockScaleObserver> observer_;
|
| };
|
|
|
| -TEST_F(QualityScalerTest, UsesOriginalFrameInitially) {
|
| - ExpectOriginalFrame();
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, ReportsOriginalResolutionInitially) {
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - QualityScaler::Resolution res = qs_.GetScaledResolution();
|
| - EXPECT_EQ(input_frame_->width(), res.width);
|
| - EXPECT_EQ(input_frame_->height(), res.height);
|
| -}
|
| -
|
| TEST_F(QualityScalerTest, DownscalesAfterContinuousFramedrop) {
|
| - EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within " << kNumSeconds
|
| - << " seconds.";
|
| - QualityScaler::Resolution res = qs_.GetScaledResolution();
|
| - EXPECT_LT(res.width, input_frame_->width());
|
| - EXPECT_LT(res.height, input_frame_->height());
|
| + q_->PostTask([this] { TriggerScale(kScaleDown); });
|
| + EXPECT_TRUE(observer_->event.Wait(50));
|
| + EXPECT_EQ(1, observer_->scaled_down);
|
| }
|
|
|
| TEST_F(QualityScalerTest, KeepsScaleAtHighQp) {
|
| - EXPECT_FALSE(TriggerScale(kKeepScaleAtHighQp))
|
| - << "Downscale at high threshold which should keep scale.";
|
| - QualityScaler::Resolution res = qs_.GetScaledResolution();
|
| - EXPECT_EQ(res.width, input_frame_->width());
|
| - EXPECT_EQ(res.height, input_frame_->height());
|
| + q_->PostTask([this] { TriggerScale(kKeepScaleAtHighQp); });
|
| + EXPECT_FALSE(observer_->event.Wait(50));
|
| + EXPECT_EQ(0, observer_->scaled_down);
|
| + EXPECT_EQ(0, observer_->scaled_up);
|
| }
|
|
|
| TEST_F(QualityScalerTest, DownscalesAboveHighQp) {
|
| - EXPECT_TRUE(TriggerScale(kScaleDownAboveHighQp))
|
| - << "No downscale within " << kNumSeconds << " seconds.";
|
| - QualityScaler::Resolution res = qs_.GetScaledResolution();
|
| - EXPECT_LT(res.width, input_frame_->width());
|
| - EXPECT_LT(res.height, input_frame_->height());
|
| + q_->PostTask([this] { TriggerScale(kScaleDownAboveHighQp); });
|
| + EXPECT_TRUE(observer_->event.Wait(50));
|
| + EXPECT_EQ(1, observer_->scaled_down);
|
| + EXPECT_EQ(0, observer_->scaled_up);
|
| }
|
|
|
| TEST_F(QualityScalerTest, DownscalesAfterTwoThirdsFramedrop) {
|
| - for (int i = 0; i < kFramerate * kNumSeconds / 3; ++i) {
|
| - qs_.ReportQP(kNormalQp);
|
| - qs_.ReportDroppedFrame();
|
| - qs_.ReportDroppedFrame();
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - if (qs_.GetScaledResolution().width < input_frame_->width())
|
| - return;
|
| - }
|
| -
|
| - FAIL() << "No downscale within " << kNumSeconds << " seconds.";
|
| + q_->PostTask([this] {
|
| + qs_->ReportDroppedFrame();
|
| + qs_->ReportDroppedFrame();
|
| + qs_->ReportQP(kHighQp);
|
| + });
|
| + EXPECT_TRUE(observer_->event.Wait(50));
|
| + EXPECT_EQ(1, observer_->scaled_down);
|
| + EXPECT_EQ(0, observer_->scaled_up);
|
| }
|
|
|
| TEST_F(QualityScalerTest, DoesNotDownscaleOnNormalQp) {
|
| - for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
|
| - qs_.ReportQP(kNormalQp);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
|
| - << "Unexpected scale on half framedrop.";
|
| - }
|
| + q_->PostTask([this] { TriggerScale(kScaleDownAboveHighQp); });
|
| + EXPECT_TRUE(observer_->event.Wait(50));
|
| + EXPECT_EQ(1, observer_->scaled_down);
|
| + EXPECT_EQ(0, observer_->scaled_up);
|
| }
|
|
|
| TEST_F(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) {
|
| - for (int i = 0; i < kFramerate * kNumSeconds / 2; ++i) {
|
| - qs_.ReportQP(kNormalQp);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
|
| - << "Unexpected scale on half framedrop.";
|
| -
|
| - qs_.ReportDroppedFrame();
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
|
| - << "Unexpected scale on half framedrop.";
|
| - }
|
| -}
|
| -
|
| -void QualityScalerTest::ContinuouslyDownscalesByHalfDimensionsAndBackUp() {
|
| - const int initial_min_dimension =
|
| - input_frame_->width() < input_frame_->height() ? input_frame_->width()
|
| - : input_frame_->height();
|
| - int min_dimension = initial_min_dimension;
|
| - int current_shift = 0;
|
| - // Drop all frames to force-trigger downscaling.
|
| - while (min_dimension >= 2 * kMinDownscaleDimension) {
|
| - EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within "
|
| - << kNumSeconds << " seconds.";
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - QualityScaler::Resolution res = qs_.GetScaledResolution();
|
| - min_dimension = res.width < res.height ? res.width : res.height;
|
| - ++current_shift;
|
| - ASSERT_EQ(input_frame_->width() >> current_shift, res.width);
|
| - ASSERT_EQ(input_frame_->height() >> current_shift, res.height);
|
| - ExpectScaleUsingReportedResolution();
|
| - }
|
| -
|
| - // Make sure we can scale back with good-quality frames.
|
| - while (min_dimension < initial_min_dimension) {
|
| - EXPECT_TRUE(TriggerScale(kScaleUp)) << "No upscale within " << kNumSeconds
|
| - << " seconds.";
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - QualityScaler::Resolution res = qs_.GetScaledResolution();
|
| - min_dimension = res.width < res.height ? res.width : res.height;
|
| - --current_shift;
|
| - ASSERT_EQ(input_frame_->width() >> current_shift, res.width);
|
| - ASSERT_EQ(input_frame_->height() >> current_shift, res.height);
|
| - ExpectScaleUsingReportedResolution();
|
| - }
|
| -
|
| - // Verify we don't start upscaling after further low use.
|
| - for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
|
| - qs_.ReportQP(kLowQp);
|
| - ExpectOriginalFrame();
|
| - }
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, ContinuouslyDownscalesByHalfDimensionsAndBackUp) {
|
| - ContinuouslyDownscalesByHalfDimensionsAndBackUp();
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest,
|
| - ContinuouslyDownscalesOddResolutionsByHalfDimensionsAndBackUp) {
|
| - const int kOddWidth = 517;
|
| - const int kOddHeight = 1239;
|
| - input_frame_ = I420Buffer::Create(kOddWidth, kOddHeight);
|
| - ContinuouslyDownscalesByHalfDimensionsAndBackUp();
|
| -}
|
| -
|
| -void QualityScalerTest::DoesNotDownscaleFrameDimensions(int width, int height) {
|
| - input_frame_ = I420Buffer::Create(width, height);
|
| -
|
| - for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
|
| - qs_.ReportDroppedFrame();
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
|
| - << "Unexpected scale of minimal-size frame.";
|
| - }
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DoesNotDownscaleFrom1PxWidth) {
|
| - DoesNotDownscaleFrameDimensions(1, kHeight);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DoesNotDownscaleFrom1PxHeight) {
|
| - DoesNotDownscaleFrameDimensions(kWidth, 1);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DoesNotDownscaleFrom1Px) {
|
| - DoesNotDownscaleFrameDimensions(1, 1);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsWidth) {
|
| - DoesNotDownscaleFrameDimensions(
|
| - 2 * kMinDownscaleDimension - 1, 1000);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsHeight) {
|
| - DoesNotDownscaleFrameDimensions(
|
| - 1000, 2 * kMinDownscaleDimension - 1);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DownscaleToVgaOnLowInitialBitrate) {
|
| - static const int kWidth720p = 1280;
|
| - static const int kHeight720p = 720;
|
| - static const int kInitialBitrateKbps = 300;
|
| - input_frame_ = I420Buffer::Create(kWidth720p, kHeight720p);
|
| - qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, kInitialBitrateKbps,
|
| - kWidth720p, kHeight720p, kFramerate);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - int init_width = qs_.GetScaledResolution().width;
|
| - int init_height = qs_.GetScaledResolution().height;
|
| - EXPECT_EQ(640, init_width);
|
| - EXPECT_EQ(360, init_height);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DownscaleToQvgaOnLowerInitialBitrate) {
|
| - static const int kWidth720p = 1280;
|
| - static const int kHeight720p = 720;
|
| - static const int kInitialBitrateKbps = 200;
|
| - input_frame_ = I420Buffer::Create(kWidth720p, kHeight720p);
|
| - qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, kInitialBitrateKbps,
|
| - kWidth720p, kHeight720p, kFramerate);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - int init_width = qs_.GetScaledResolution().width;
|
| - int init_height = qs_.GetScaledResolution().height;
|
| - EXPECT_EQ(320, init_width);
|
| - EXPECT_EQ(180, init_height);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DownscaleAfterMeasuredSecondsThenSlowerBackUp) {
|
| - qs_.Init(kLowQpThreshold, kHighQp, 0, kWidth, kHeight, kFramerate);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - QualityScaler::Resolution initial_res = qs_.GetScaledResolution();
|
| -
|
| - // Should not downscale if less than kMeasureSecondsDownscale seconds passed.
|
| - for (int i = 0; i < kFramerate * kMeasureSecondsDownscale - 1; ++i) {
|
| - qs_.ReportQP(kHighQp + 1);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - }
|
| - EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width);
|
| - EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height);
|
| -
|
| - // Should downscale if more than kMeasureSecondsDownscale seconds passed (add
|
| - // last frame).
|
| - qs_.ReportQP(kHighQp + 1);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - EXPECT_GT(initial_res.width, qs_.GetScaledResolution().width);
|
| - EXPECT_GT(initial_res.height, qs_.GetScaledResolution().height);
|
| -
|
| - // Should not upscale if less than kMeasureSecondsUpscale seconds passed since
|
| - // we saw issues initially (have already gone down).
|
| - for (int i = 0; i < kFramerate * kMeasureSecondsUpscale - 1; ++i) {
|
| - qs_.ReportQP(kLowQp);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - }
|
| - EXPECT_GT(initial_res.width, qs_.GetScaledResolution().width);
|
| - EXPECT_GT(initial_res.height, qs_.GetScaledResolution().height);
|
| -
|
| - // Should upscale (back to initial) if kMeasureSecondsUpscale seconds passed
|
| - // (add last frame).
|
| - qs_.ReportQP(kLowQp);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width);
|
| - EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, UpscaleQuicklyInitiallyAfterMeasuredSeconds) {
|
| - qs_.Init(kLowQpThreshold, kHighQp, kLowInitialBitrateKbps, kWidth, kHeight,
|
| - kFramerate);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - QualityScaler::Resolution initial_res = qs_.GetScaledResolution();
|
| -
|
| - // Should not upscale if less than kMeasureSecondsFastUpscale seconds passed.
|
| - for (int i = 0; i < kFramerate * kMeasureSecondsFastUpscale - 1; ++i) {
|
| - qs_.ReportQP(kLowQp);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - }
|
| - EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width);
|
| - EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height);
|
| -
|
| - // Should upscale if kMeasureSecondsFastUpscale seconds passed (add last
|
| - // frame).
|
| - qs_.ReportQP(kLowQp);
|
| - qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
|
| - EXPECT_LT(initial_res.width, qs_.GetScaledResolution().width);
|
| - EXPECT_LT(initial_res.height, qs_.GetScaledResolution().height);
|
| -}
|
| -
|
| -void QualityScalerTest::DownscaleEndsAt(int input_width,
|
| - int input_height,
|
| - int end_width,
|
| - int end_height) {
|
| - // Create a frame with 2x expected end width/height to verify that we can
|
| - // scale down to expected end width/height.
|
| - input_frame_ = I420Buffer::Create(input_width, input_height);
|
| -
|
| - int last_width = input_width;
|
| - int last_height = input_height;
|
| - // Drop all frames to force-trigger downscaling.
|
| - while (true) {
|
| - TriggerScale(kScaleDown);
|
| - QualityScaler::Resolution res = qs_.GetScaledResolution();
|
| - if (last_width == res.width) {
|
| - EXPECT_EQ(last_height, res.height);
|
| - EXPECT_EQ(end_width, res.width);
|
| - EXPECT_EQ(end_height, res.height);
|
| - break;
|
| - }
|
| - last_width = res.width;
|
| - last_height = res.height;
|
| - }
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DownscalesTo320x180) {
|
| - DownscaleEndsAt(640, 360, 320, 180);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DownscalesTo180x320) {
|
| - DownscaleEndsAt(360, 640, 180, 320);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DownscalesFrom1280x720To320x180) {
|
| - DownscaleEndsAt(1280, 720, 320, 180);
|
| -}
|
| -
|
| -TEST_F(QualityScalerTest, DoesntDownscaleInitialQvga) {
|
| - DownscaleEndsAt(320, 180, 320, 180);
|
| + q_->PostTask([this] {
|
| + qs_->ReportDroppedFrame();
|
| + qs_->ReportQP(kHighQp);
|
| + });
|
| + EXPECT_FALSE(observer_->event.Wait(50));
|
| + EXPECT_EQ(0, observer_->scaled_down);
|
| + EXPECT_EQ(0, observer_->scaled_up);
|
| +}
|
| +
|
| +TEST_F(QualityScalerTest, UpscalesAfterLowQp) {
|
| + q_->PostTask([this] { TriggerScale(kScaleUp); });
|
| + EXPECT_TRUE(observer_->event.Wait(50));
|
| + EXPECT_EQ(0, observer_->scaled_down);
|
| + EXPECT_EQ(1, observer_->scaled_up);
|
| +}
|
| +
|
| +TEST_F(QualityScalerTest, ScalesDownAndBackUp) {
|
| + q_->PostTask([this] { TriggerScale(kScaleDown); });
|
| + EXPECT_TRUE(observer_->event.Wait(50));
|
| + EXPECT_EQ(1, observer_->scaled_down);
|
| + EXPECT_EQ(0, observer_->scaled_up);
|
| + q_->PostTask([this] { TriggerScale(kScaleUp); });
|
| + EXPECT_TRUE(observer_->event.Wait(50));
|
| + EXPECT_EQ(1, observer_->scaled_down);
|
| + EXPECT_EQ(1, observer_->scaled_up);
|
| }
|
|
|
| } // namespace webrtc
|
|
|