Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: webrtc/modules/video_coding/utility/quality_scaler_unittest.cc

Issue 1160403004: Add default downscale threshold to QualityScaler. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: requested tests Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/video_coding/utility/quality_scaler.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 13 matching lines...) Expand all
24 static const int kMaxQp = 56; 24 static const int kMaxQp = 56;
25 } // namespace 25 } // namespace
26 26
27 class QualityScalerTest : public ::testing::Test { 27 class QualityScalerTest : public ::testing::Test {
28 protected: 28 protected:
29 enum ScaleDirection { kScaleDown, kScaleUp }; 29 enum ScaleDirection { kScaleDown, kScaleUp };
30 30
31 QualityScalerTest() { 31 QualityScalerTest() {
32 input_frame_.CreateEmptyFrame( 32 input_frame_.CreateEmptyFrame(
33 kWidth, kHeight, kWidth, kHalfWidth, kHalfWidth); 33 kWidth, kHeight, kWidth, kHalfWidth, kHalfWidth);
34 qs_.Init(kMaxQp / kDefaultLowQpDenominator); 34 qs_.Init(kMaxQp / QualityScaler::kDefaultLowQpDenominator);
35 qs_.ReportFramerate(kFramerate); 35 qs_.ReportFramerate(kFramerate);
36 } 36 }
37 37
38 void TriggerScale(ScaleDirection scale_direction) { 38 bool TriggerScale(ScaleDirection scale_direction) {
39 int initial_width = qs_.GetScaledResolution(input_frame_).width; 39 int initial_width = qs_.GetScaledResolution(input_frame_).width;
40 for (int i = 0; i < kFramerate * kNumSeconds; ++i) { 40 for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
41 switch (scale_direction) { 41 switch (scale_direction) {
42 case kScaleUp: 42 case kScaleUp:
43 qs_.ReportQP(kLowQp); 43 qs_.ReportQP(kLowQp);
44 break; 44 break;
45 case kScaleDown: 45 case kScaleDown:
46 qs_.ReportDroppedFrame(); 46 qs_.ReportDroppedFrame();
47 break; 47 break;
48 } 48 }
49 49
50 if (qs_.GetScaledResolution(input_frame_).width != initial_width) 50 if (qs_.GetScaledResolution(input_frame_).width != initial_width)
51 return; 51 return true;
52 } 52 }
53 53
54 FAIL() << "No downscale within " << kNumSeconds << " seconds."; 54 return false;
55 } 55 }
56 56
57 void ExpectOriginalFrame() { 57 void ExpectOriginalFrame() {
58 EXPECT_EQ(&input_frame_, &qs_.GetScaledFrame(input_frame_)) 58 EXPECT_EQ(&input_frame_, &qs_.GetScaledFrame(input_frame_))
59 << "Using scaled frame instead of original input."; 59 << "Using scaled frame instead of original input.";
60 } 60 }
61 61
62 void ExpectScaleUsingReportedResolution() { 62 void ExpectScaleUsingReportedResolution() {
63 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_); 63 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_);
64 const VideoFrame& scaled_frame = qs_.GetScaledFrame(input_frame_); 64 const VideoFrame& scaled_frame = qs_.GetScaledFrame(input_frame_);
65 EXPECT_EQ(res.width, scaled_frame.width()); 65 EXPECT_EQ(res.width, scaled_frame.width());
66 EXPECT_EQ(res.height, scaled_frame.height()); 66 EXPECT_EQ(res.height, scaled_frame.height());
67 } 67 }
68 68
69 void ContinuouslyDownscalesByHalfDimensionsAndBackUp(); 69 void ContinuouslyDownscalesByHalfDimensionsAndBackUp();
70 70
71 void DoesNotDownscaleFrameDimensions(int width, int height); 71 void DoesNotDownscaleFrameDimensions(int width, int height);
72 72
73 void DownscaleEndsAt(int input_width,
74 int input_height,
75 int end_width,
76 int end_height);
77
73 QualityScaler qs_; 78 QualityScaler qs_;
74 VideoFrame input_frame_; 79 VideoFrame input_frame_;
75 }; 80 };
76 81
77 TEST_F(QualityScalerTest, UsesOriginalFrameInitially) { 82 TEST_F(QualityScalerTest, UsesOriginalFrameInitially) {
78 ExpectOriginalFrame(); 83 ExpectOriginalFrame();
79 } 84 }
80 85
81 TEST_F(QualityScalerTest, ReportsOriginalResolutionInitially) { 86 TEST_F(QualityScalerTest, ReportsOriginalResolutionInitially) {
82 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_); 87 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_);
83 EXPECT_EQ(input_frame_.width(), res.width); 88 EXPECT_EQ(input_frame_.width(), res.width);
84 EXPECT_EQ(input_frame_.height(), res.height); 89 EXPECT_EQ(input_frame_.height(), res.height);
85 } 90 }
86 91
87 TEST_F(QualityScalerTest, DownscalesAfterContinuousFramedrop) { 92 TEST_F(QualityScalerTest, DownscalesAfterContinuousFramedrop) {
88 TriggerScale(kScaleDown); 93 EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within " << kNumSeconds
94 << " seconds.";
89 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_); 95 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_);
90 EXPECT_LT(res.width, input_frame_.width()); 96 EXPECT_LT(res.width, input_frame_.width());
91 EXPECT_LT(res.height, input_frame_.height()); 97 EXPECT_LT(res.height, input_frame_.height());
92 } 98 }
93 99
94 TEST_F(QualityScalerTest, DownscalesAfterTwoThirdsFramedrop) { 100 TEST_F(QualityScalerTest, DownscalesAfterTwoThirdsFramedrop) {
95 for (int i = 0; i < kFramerate * kNumSeconds / 3; ++i) { 101 for (int i = 0; i < kFramerate * kNumSeconds / 3; ++i) {
96 qs_.ReportQP(kNormalQp); 102 qs_.ReportQP(kNormalQp);
97 qs_.ReportDroppedFrame(); 103 qs_.ReportDroppedFrame();
98 qs_.ReportDroppedFrame(); 104 qs_.ReportDroppedFrame();
(...skipping 24 matching lines...) Expand all
123 } 129 }
124 } 130 }
125 131
126 void QualityScalerTest::ContinuouslyDownscalesByHalfDimensionsAndBackUp() { 132 void QualityScalerTest::ContinuouslyDownscalesByHalfDimensionsAndBackUp() {
127 const int initial_min_dimension = input_frame_.width() < input_frame_.height() 133 const int initial_min_dimension = input_frame_.width() < input_frame_.height()
128 ? input_frame_.width() 134 ? input_frame_.width()
129 : input_frame_.height(); 135 : input_frame_.height();
130 int min_dimension = initial_min_dimension; 136 int min_dimension = initial_min_dimension;
131 int current_shift = 0; 137 int current_shift = 0;
132 // Drop all frames to force-trigger downscaling. 138 // Drop all frames to force-trigger downscaling.
133 while (min_dimension > 16) { 139 while (min_dimension >= 2 * QualityScaler::kDefaultMinDownscaleDimension) {
134 TriggerScale(kScaleDown); 140 EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within "
141 << kNumSeconds << " seconds.";
135 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_); 142 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_);
136 min_dimension = res.width < res.height ? res.width : res.height; 143 min_dimension = res.width < res.height ? res.width : res.height;
137 ++current_shift; 144 ++current_shift;
138 ASSERT_EQ(input_frame_.width() >> current_shift, res.width); 145 ASSERT_EQ(input_frame_.width() >> current_shift, res.width);
139 ASSERT_EQ(input_frame_.height() >> current_shift, res.height); 146 ASSERT_EQ(input_frame_.height() >> current_shift, res.height);
140 ExpectScaleUsingReportedResolution(); 147 ExpectScaleUsingReportedResolution();
141 } 148 }
142 149
143 // Make sure we can scale back with good-quality frames. 150 // Make sure we can scale back with good-quality frames.
144 while (min_dimension < initial_min_dimension) { 151 while (min_dimension < initial_min_dimension) {
145 TriggerScale(kScaleUp); 152 EXPECT_TRUE(TriggerScale(kScaleUp)) << "No upscale within " << kNumSeconds
153 << " seconds.";
146 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_); 154 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_);
147 min_dimension = res.width < res.height ? res.width : res.height; 155 min_dimension = res.width < res.height ? res.width : res.height;
148 --current_shift; 156 --current_shift;
149 ASSERT_EQ(input_frame_.width() >> current_shift, res.width); 157 ASSERT_EQ(input_frame_.width() >> current_shift, res.width);
150 ASSERT_EQ(input_frame_.height() >> current_shift, res.height); 158 ASSERT_EQ(input_frame_.height() >> current_shift, res.height);
151 ExpectScaleUsingReportedResolution(); 159 ExpectScaleUsingReportedResolution();
152 } 160 }
153 161
154 // Verify we don't start upscaling after further low use. 162 // Verify we don't start upscaling after further low use.
155 for (int i = 0; i < kFramerate * kNumSeconds; ++i) { 163 for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 } 196 }
189 197
190 TEST_F(QualityScalerTest, DoesNotDownscaleFrom1PxHeight) { 198 TEST_F(QualityScalerTest, DoesNotDownscaleFrom1PxHeight) {
191 DoesNotDownscaleFrameDimensions(kWidth, 1); 199 DoesNotDownscaleFrameDimensions(kWidth, 1);
192 } 200 }
193 201
194 TEST_F(QualityScalerTest, DoesNotDownscaleFrom1Px) { 202 TEST_F(QualityScalerTest, DoesNotDownscaleFrom1Px) {
195 DoesNotDownscaleFrameDimensions(1, 1); 203 DoesNotDownscaleFrameDimensions(1, 1);
196 } 204 }
197 205
206 TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsWidth) {
207 DoesNotDownscaleFrameDimensions(
208 2 * QualityScaler::kDefaultMinDownscaleDimension - 1, 1000);
209 }
210
211 TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsHeight) {
212 DoesNotDownscaleFrameDimensions(
213 1000, 2 * QualityScaler::kDefaultMinDownscaleDimension - 1);
214 }
215
216 void QualityScalerTest::DownscaleEndsAt(int input_width,
217 int input_height,
218 int end_width,
219 int end_height) {
220 // Create a frame with 2x expected end width/height to verify that we can
221 // scale down to expected end width/height.
222 input_frame_.CreateEmptyFrame(input_width, input_height, input_width,
223 (input_width + 1) / 2, (input_width + 1) / 2);
224
225 int last_width = input_width;
226 int last_height = input_height;
227 // Drop all frames to force-trigger downscaling.
228 while (true) {
229 TriggerScale(kScaleDown);
230 QualityScaler::Resolution res = qs_.GetScaledResolution(input_frame_);
231 if (last_width == res.width) {
232 EXPECT_EQ(last_height, res.height);
233 EXPECT_EQ(end_width, res.width);
234 EXPECT_EQ(end_height, res.height);
235 break;
236 }
237 last_width = res.width;
238 last_height = res.height;
239 }
240 }
241
242 TEST_F(QualityScalerTest, DefaultDownscalesTo160x90) {
243 DownscaleEndsAt(320, 180, 160, 90);
244 }
245
246 TEST_F(QualityScalerTest, DefaultDownscalesTo90x160) {
247 DownscaleEndsAt(180, 320, 90, 160);
248 }
249
250 TEST_F(QualityScalerTest, DefaultDownscalesFrom1280x720To160x90) {
251 DownscaleEndsAt(1280, 720, 160, 90);
252 }
253
254 TEST_F(QualityScalerTest, DefaultDoesntDownscaleBelow160x90) {
255 DownscaleEndsAt(320 - 1, 180 - 1, 320 - 1, 180 - 1);
256 }
257
258 TEST_F(QualityScalerTest, DefaultDoesntDownscaleBelow90x160) {
259 DownscaleEndsAt(180 - 1, 320 - 1, 180 - 1, 320 - 1);
260 }
261
262 TEST_F(QualityScalerTest, RespectsMinResolutionWidth) {
263 // Should end at 200x100, as width can't go lower.
264 qs_.SetMinResolution(200, 10);
265 DownscaleEndsAt(1600, 800, 200, 100);
266 }
267
268 TEST_F(QualityScalerTest, RespectsMinResolutionHeight) {
269 // Should end at 100x200, as height can't go lower.
270 qs_.SetMinResolution(10, 200);
271 DownscaleEndsAt(800, 1600, 100, 200);
272 }
273
198 } // namespace webrtc 274 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/utility/quality_scaler.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698