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

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

Issue 2020593002: Refactor scaling. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Trivial rebase. Created 4 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
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
11 #include "webrtc/modules/video_coding/utility/quality_scaler.h" 11 #include "webrtc/modules/video_coding/utility/quality_scaler.h"
12 12
13 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
14 14
15 namespace webrtc { 15 namespace webrtc {
16 namespace { 16 namespace {
17 static const int kNumSeconds = 10; 17 static const int kNumSeconds = 10;
18 static const int kWidth = 1920; 18 static const int kWidth = 1920;
19 static const int kHalfWidth = kWidth / 2;
20 static const int kHeight = 1080; 19 static const int kHeight = 1080;
21 static const int kFramerate = 30; 20 static const int kFramerate = 30;
22 static const int kLowQp = 15; 21 static const int kLowQp = 15;
23 static const int kNormalQp = 30; 22 static const int kNormalQp = 30;
24 static const int kLowQpThreshold = 18; 23 static const int kLowQpThreshold = 18;
25 static const int kHighQp = 40; 24 static const int kHighQp = 40;
26 static const int kDisabledBadQpThreshold = 64; 25 static const int kDisabledBadQpThreshold = 64;
27 static const int kLowInitialBitrateKbps = 300; 26 static const int kLowInitialBitrateKbps = 300;
28 // These values need to be in sync with corresponding constants 27 // These values need to be in sync with corresponding constants
29 // in quality_scaler.cc 28 // in quality_scaler.cc
30 static const int kMeasureSecondsFastUpscale = 2; 29 static const int kMeasureSecondsFastUpscale = 2;
31 static const int kMeasureSecondsUpscale = 5; 30 static const int kMeasureSecondsUpscale = 5;
32 static const int kMeasureSecondsDownscale = 5; 31 static const int kMeasureSecondsDownscale = 5;
33 static const int kMinDownscaleDimension = 140; 32 static const int kMinDownscaleDimension = 140;
34 } // namespace 33 } // namespace
35 34
36 class QualityScalerTest : public ::testing::Test { 35 class QualityScalerTest : public ::testing::Test {
37 protected: 36 protected:
38 enum ScaleDirection { 37 enum ScaleDirection {
39 kKeepScaleAtHighQp, 38 kKeepScaleAtHighQp,
40 kScaleDown, 39 kScaleDown,
41 kScaleDownAboveHighQp, 40 kScaleDownAboveHighQp,
42 kScaleUp 41 kScaleUp
43 }; 42 };
44 43
45 QualityScalerTest() { 44 QualityScalerTest() {
46 input_frame_.CreateEmptyFrame(kWidth, kHeight, kWidth, kHalfWidth, 45 input_frame_ = rtc::scoped_refptr<VideoFrameBuffer>(
47 kHalfWidth); 46 new rtc::RefCountedObject<I420Buffer>(kWidth, kHeight));
48 qs_.Init(kLowQpThreshold, kHighQp, 0, 0, 0, kFramerate); 47 qs_.Init(kLowQpThreshold, kHighQp, 0, 0, 0, kFramerate);
49 qs_.OnEncodeFrame(input_frame_); 48 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
50 } 49 }
51 50
52 bool TriggerScale(ScaleDirection scale_direction) { 51 bool TriggerScale(ScaleDirection scale_direction) {
53 qs_.OnEncodeFrame(input_frame_); 52 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
54 int initial_width = qs_.GetScaledResolution().width; 53 int initial_width = qs_.GetScaledResolution().width;
55 for (int i = 0; i < kFramerate * kNumSeconds; ++i) { 54 for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
56 switch (scale_direction) { 55 switch (scale_direction) {
57 case kScaleUp: 56 case kScaleUp:
58 qs_.ReportQP(kLowQp); 57 qs_.ReportQP(kLowQp);
59 break; 58 break;
60 case kScaleDown: 59 case kScaleDown:
61 qs_.ReportDroppedFrame(); 60 qs_.ReportDroppedFrame();
62 break; 61 break;
63 case kKeepScaleAtHighQp: 62 case kKeepScaleAtHighQp:
64 qs_.ReportQP(kHighQp); 63 qs_.ReportQP(kHighQp);
65 break; 64 break;
66 case kScaleDownAboveHighQp: 65 case kScaleDownAboveHighQp:
67 qs_.ReportQP(kHighQp + 1); 66 qs_.ReportQP(kHighQp + 1);
68 break; 67 break;
69 } 68 }
70 qs_.OnEncodeFrame(input_frame_); 69 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
71 if (qs_.GetScaledResolution().width != initial_width) 70 if (qs_.GetScaledResolution().width != initial_width)
72 return true; 71 return true;
73 } 72 }
74 73
75 return false; 74 return false;
76 } 75 }
77 76
78 void ExpectOriginalFrame() { 77 void ExpectOriginalFrame() {
79 EXPECT_EQ(&input_frame_, &qs_.GetScaledFrame(input_frame_)) 78 EXPECT_EQ(input_frame_, qs_.GetScaledBuffer(input_frame_))
80 << "Using scaled frame instead of original input."; 79 << "Using scaled frame instead of original input.";
81 } 80 }
82 81
83 void ExpectScaleUsingReportedResolution() { 82 void ExpectScaleUsingReportedResolution() {
84 qs_.OnEncodeFrame(input_frame_); 83 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
85 QualityScaler::Resolution res = qs_.GetScaledResolution(); 84 QualityScaler::Resolution res = qs_.GetScaledResolution();
86 const VideoFrame& scaled_frame = qs_.GetScaledFrame(input_frame_); 85 rtc::scoped_refptr<VideoFrameBuffer> scaled_frame =
87 EXPECT_EQ(res.width, scaled_frame.width()); 86 qs_.GetScaledBuffer(input_frame_);
88 EXPECT_EQ(res.height, scaled_frame.height()); 87 EXPECT_EQ(res.width, scaled_frame->width());
88 EXPECT_EQ(res.height, scaled_frame->height());
89 } 89 }
90 90
91 void ContinuouslyDownscalesByHalfDimensionsAndBackUp(); 91 void ContinuouslyDownscalesByHalfDimensionsAndBackUp();
92 92
93 void DoesNotDownscaleFrameDimensions(int width, int height); 93 void DoesNotDownscaleFrameDimensions(int width, int height);
94 94
95 void DownscaleEndsAt(int input_width, 95 void DownscaleEndsAt(int input_width,
96 int input_height, 96 int input_height,
97 int end_width, 97 int end_width,
98 int end_height); 98 int end_height);
99 99
100 QualityScaler qs_; 100 QualityScaler qs_;
101 VideoFrame input_frame_; 101 rtc::scoped_refptr<VideoFrameBuffer> input_frame_;
102 }; 102 };
103 103
104 TEST_F(QualityScalerTest, UsesOriginalFrameInitially) { 104 TEST_F(QualityScalerTest, UsesOriginalFrameInitially) {
105 ExpectOriginalFrame(); 105 ExpectOriginalFrame();
106 } 106 }
107 107
108 TEST_F(QualityScalerTest, ReportsOriginalResolutionInitially) { 108 TEST_F(QualityScalerTest, ReportsOriginalResolutionInitially) {
109 qs_.OnEncodeFrame(input_frame_); 109 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
110 QualityScaler::Resolution res = qs_.GetScaledResolution(); 110 QualityScaler::Resolution res = qs_.GetScaledResolution();
111 EXPECT_EQ(input_frame_.width(), res.width); 111 EXPECT_EQ(input_frame_->width(), res.width);
112 EXPECT_EQ(input_frame_.height(), res.height); 112 EXPECT_EQ(input_frame_->height(), res.height);
113 } 113 }
114 114
115 TEST_F(QualityScalerTest, DownscalesAfterContinuousFramedrop) { 115 TEST_F(QualityScalerTest, DownscalesAfterContinuousFramedrop) {
116 EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within " << kNumSeconds 116 EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within " << kNumSeconds
117 << " seconds."; 117 << " seconds.";
118 QualityScaler::Resolution res = qs_.GetScaledResolution(); 118 QualityScaler::Resolution res = qs_.GetScaledResolution();
119 EXPECT_LT(res.width, input_frame_.width()); 119 EXPECT_LT(res.width, input_frame_->width());
120 EXPECT_LT(res.height, input_frame_.height()); 120 EXPECT_LT(res.height, input_frame_->height());
121 } 121 }
122 122
123 TEST_F(QualityScalerTest, KeepsScaleAtHighQp) { 123 TEST_F(QualityScalerTest, KeepsScaleAtHighQp) {
124 EXPECT_FALSE(TriggerScale(kKeepScaleAtHighQp)) 124 EXPECT_FALSE(TriggerScale(kKeepScaleAtHighQp))
125 << "Downscale at high threshold which should keep scale."; 125 << "Downscale at high threshold which should keep scale.";
126 QualityScaler::Resolution res = qs_.GetScaledResolution(); 126 QualityScaler::Resolution res = qs_.GetScaledResolution();
127 EXPECT_EQ(res.width, input_frame_.width()); 127 EXPECT_EQ(res.width, input_frame_->width());
128 EXPECT_EQ(res.height, input_frame_.height()); 128 EXPECT_EQ(res.height, input_frame_->height());
129 } 129 }
130 130
131 TEST_F(QualityScalerTest, DownscalesAboveHighQp) { 131 TEST_F(QualityScalerTest, DownscalesAboveHighQp) {
132 EXPECT_TRUE(TriggerScale(kScaleDownAboveHighQp)) 132 EXPECT_TRUE(TriggerScale(kScaleDownAboveHighQp))
133 << "No downscale within " << kNumSeconds << " seconds."; 133 << "No downscale within " << kNumSeconds << " seconds.";
134 QualityScaler::Resolution res = qs_.GetScaledResolution(); 134 QualityScaler::Resolution res = qs_.GetScaledResolution();
135 EXPECT_LT(res.width, input_frame_.width()); 135 EXPECT_LT(res.width, input_frame_->width());
136 EXPECT_LT(res.height, input_frame_.height()); 136 EXPECT_LT(res.height, input_frame_->height());
137 } 137 }
138 138
139 TEST_F(QualityScalerTest, DownscalesAfterTwoThirdsFramedrop) { 139 TEST_F(QualityScalerTest, DownscalesAfterTwoThirdsFramedrop) {
140 for (int i = 0; i < kFramerate * kNumSeconds / 3; ++i) { 140 for (int i = 0; i < kFramerate * kNumSeconds / 3; ++i) {
141 qs_.ReportQP(kNormalQp); 141 qs_.ReportQP(kNormalQp);
142 qs_.ReportDroppedFrame(); 142 qs_.ReportDroppedFrame();
143 qs_.ReportDroppedFrame(); 143 qs_.ReportDroppedFrame();
144 qs_.OnEncodeFrame(input_frame_); 144 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
145 if (qs_.GetScaledResolution().width < input_frame_.width()) 145 if (qs_.GetScaledResolution().width < input_frame_->width())
146 return; 146 return;
147 } 147 }
148 148
149 FAIL() << "No downscale within " << kNumSeconds << " seconds."; 149 FAIL() << "No downscale within " << kNumSeconds << " seconds.";
150 } 150 }
151 151
152 TEST_F(QualityScalerTest, DoesNotDownscaleOnNormalQp) { 152 TEST_F(QualityScalerTest, DoesNotDownscaleOnNormalQp) {
153 for (int i = 0; i < kFramerate * kNumSeconds; ++i) { 153 for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
154 qs_.ReportQP(kNormalQp); 154 qs_.ReportQP(kNormalQp);
155 qs_.OnEncodeFrame(input_frame_); 155 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
156 ASSERT_EQ(input_frame_.width(), qs_.GetScaledResolution().width) 156 ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
157 << "Unexpected scale on half framedrop."; 157 << "Unexpected scale on half framedrop.";
158 } 158 }
159 } 159 }
160 160
161 TEST_F(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) { 161 TEST_F(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) {
162 for (int i = 0; i < kFramerate * kNumSeconds / 2; ++i) { 162 for (int i = 0; i < kFramerate * kNumSeconds / 2; ++i) {
163 qs_.ReportQP(kNormalQp); 163 qs_.ReportQP(kNormalQp);
164 qs_.OnEncodeFrame(input_frame_); 164 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
165 ASSERT_EQ(input_frame_.width(), qs_.GetScaledResolution().width) 165 ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
166 << "Unexpected scale on half framedrop."; 166 << "Unexpected scale on half framedrop.";
167 167
168 qs_.ReportDroppedFrame(); 168 qs_.ReportDroppedFrame();
169 qs_.OnEncodeFrame(input_frame_); 169 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
170 ASSERT_EQ(input_frame_.width(), qs_.GetScaledResolution().width) 170 ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
171 << "Unexpected scale on half framedrop."; 171 << "Unexpected scale on half framedrop.";
172 } 172 }
173 } 173 }
174 174
175 void QualityScalerTest::ContinuouslyDownscalesByHalfDimensionsAndBackUp() { 175 void QualityScalerTest::ContinuouslyDownscalesByHalfDimensionsAndBackUp() {
176 const int initial_min_dimension = input_frame_.width() < input_frame_.height() 176 const int initial_min_dimension =
177 ? input_frame_.width() 177 input_frame_->width() < input_frame_->height() ? input_frame_->width()
178 : input_frame_.height(); 178 : input_frame_->height();
179 int min_dimension = initial_min_dimension; 179 int min_dimension = initial_min_dimension;
180 int current_shift = 0; 180 int current_shift = 0;
181 // Drop all frames to force-trigger downscaling. 181 // Drop all frames to force-trigger downscaling.
182 while (min_dimension >= 2 * kMinDownscaleDimension) { 182 while (min_dimension >= 2 * kMinDownscaleDimension) {
183 EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within " 183 EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within "
184 << kNumSeconds << " seconds."; 184 << kNumSeconds << " seconds.";
185 qs_.OnEncodeFrame(input_frame_); 185 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
186 QualityScaler::Resolution res = qs_.GetScaledResolution(); 186 QualityScaler::Resolution res = qs_.GetScaledResolution();
187 min_dimension = res.width < res.height ? res.width : res.height; 187 min_dimension = res.width < res.height ? res.width : res.height;
188 ++current_shift; 188 ++current_shift;
189 ASSERT_EQ(input_frame_.width() >> current_shift, res.width); 189 ASSERT_EQ(input_frame_->width() >> current_shift, res.width);
190 ASSERT_EQ(input_frame_.height() >> current_shift, res.height); 190 ASSERT_EQ(input_frame_->height() >> current_shift, res.height);
191 ExpectScaleUsingReportedResolution(); 191 ExpectScaleUsingReportedResolution();
192 } 192 }
193 193
194 // Make sure we can scale back with good-quality frames. 194 // Make sure we can scale back with good-quality frames.
195 while (min_dimension < initial_min_dimension) { 195 while (min_dimension < initial_min_dimension) {
196 EXPECT_TRUE(TriggerScale(kScaleUp)) << "No upscale within " << kNumSeconds 196 EXPECT_TRUE(TriggerScale(kScaleUp)) << "No upscale within " << kNumSeconds
197 << " seconds."; 197 << " seconds.";
198 qs_.OnEncodeFrame(input_frame_); 198 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
199 QualityScaler::Resolution res = qs_.GetScaledResolution(); 199 QualityScaler::Resolution res = qs_.GetScaledResolution();
200 min_dimension = res.width < res.height ? res.width : res.height; 200 min_dimension = res.width < res.height ? res.width : res.height;
201 --current_shift; 201 --current_shift;
202 ASSERT_EQ(input_frame_.width() >> current_shift, res.width); 202 ASSERT_EQ(input_frame_->width() >> current_shift, res.width);
203 ASSERT_EQ(input_frame_.height() >> current_shift, res.height); 203 ASSERT_EQ(input_frame_->height() >> current_shift, res.height);
204 ExpectScaleUsingReportedResolution(); 204 ExpectScaleUsingReportedResolution();
205 } 205 }
206 206
207 // Verify we don't start upscaling after further low use. 207 // Verify we don't start upscaling after further low use.
208 for (int i = 0; i < kFramerate * kNumSeconds; ++i) { 208 for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
209 qs_.ReportQP(kLowQp); 209 qs_.ReportQP(kLowQp);
210 ExpectOriginalFrame(); 210 ExpectOriginalFrame();
211 } 211 }
212 } 212 }
213 213
214 TEST_F(QualityScalerTest, ContinuouslyDownscalesByHalfDimensionsAndBackUp) { 214 TEST_F(QualityScalerTest, ContinuouslyDownscalesByHalfDimensionsAndBackUp) {
215 ContinuouslyDownscalesByHalfDimensionsAndBackUp(); 215 ContinuouslyDownscalesByHalfDimensionsAndBackUp();
216 } 216 }
217 217
218 TEST_F(QualityScalerTest, 218 TEST_F(QualityScalerTest,
219 ContinuouslyDownscalesOddResolutionsByHalfDimensionsAndBackUp) { 219 ContinuouslyDownscalesOddResolutionsByHalfDimensionsAndBackUp) {
220 const int kOddWidth = 517; 220 const int kOddWidth = 517;
221 const int kHalfOddWidth = (kOddWidth + 1) / 2;
222 const int kOddHeight = 1239; 221 const int kOddHeight = 1239;
223 input_frame_.CreateEmptyFrame(kOddWidth, kOddHeight, kOddWidth, kHalfOddWidth, 222 input_frame_ = rtc::scoped_refptr<VideoFrameBuffer>(
224 kHalfOddWidth); 223 new rtc::RefCountedObject<I420Buffer>(kOddWidth, kOddHeight));
225 ContinuouslyDownscalesByHalfDimensionsAndBackUp(); 224 ContinuouslyDownscalesByHalfDimensionsAndBackUp();
226 } 225 }
227 226
228 void QualityScalerTest::DoesNotDownscaleFrameDimensions(int width, int height) { 227 void QualityScalerTest::DoesNotDownscaleFrameDimensions(int width, int height) {
229 input_frame_.CreateEmptyFrame(width, height, width, (width + 1) / 2, 228 input_frame_ = rtc::scoped_refptr<VideoFrameBuffer>(
230 (width + 1) / 2); 229 new rtc::RefCountedObject<I420Buffer>(width, height));
231 230
232 for (int i = 0; i < kFramerate * kNumSeconds; ++i) { 231 for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
233 qs_.ReportDroppedFrame(); 232 qs_.ReportDroppedFrame();
234 qs_.OnEncodeFrame(input_frame_); 233 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
235 ASSERT_EQ(input_frame_.width(), qs_.GetScaledResolution().width) 234 ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
236 << "Unexpected scale of minimal-size frame."; 235 << "Unexpected scale of minimal-size frame.";
237 } 236 }
238 } 237 }
239 238
240 TEST_F(QualityScalerTest, DoesNotDownscaleFrom1PxWidth) { 239 TEST_F(QualityScalerTest, DoesNotDownscaleFrom1PxWidth) {
241 DoesNotDownscaleFrameDimensions(1, kHeight); 240 DoesNotDownscaleFrameDimensions(1, kHeight);
242 } 241 }
243 242
244 TEST_F(QualityScalerTest, DoesNotDownscaleFrom1PxHeight) { 243 TEST_F(QualityScalerTest, DoesNotDownscaleFrom1PxHeight) {
245 DoesNotDownscaleFrameDimensions(kWidth, 1); 244 DoesNotDownscaleFrameDimensions(kWidth, 1);
(...skipping 10 matching lines...) Expand all
256 255
257 TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsHeight) { 256 TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsHeight) {
258 DoesNotDownscaleFrameDimensions( 257 DoesNotDownscaleFrameDimensions(
259 1000, 2 * kMinDownscaleDimension - 1); 258 1000, 2 * kMinDownscaleDimension - 1);
260 } 259 }
261 260
262 TEST_F(QualityScalerTest, DownscaleToVgaOnLowInitialBitrate) { 261 TEST_F(QualityScalerTest, DownscaleToVgaOnLowInitialBitrate) {
263 static const int kWidth720p = 1280; 262 static const int kWidth720p = 1280;
264 static const int kHeight720p = 720; 263 static const int kHeight720p = 720;
265 static const int kInitialBitrateKbps = 300; 264 static const int kInitialBitrateKbps = 300;
266 input_frame_.CreateEmptyFrame(kWidth720p, kHeight720p, kWidth720p, 265 input_frame_ = rtc::scoped_refptr<VideoFrameBuffer>(
267 kWidth720p / 2, kWidth720p / 2); 266 new rtc::RefCountedObject<I420Buffer>(kWidth720p, kHeight720p));
268 qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, kInitialBitrateKbps, 267 qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, kInitialBitrateKbps,
269 kWidth720p, kHeight720p, kFramerate); 268 kWidth720p, kHeight720p, kFramerate);
270 qs_.OnEncodeFrame(input_frame_); 269 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
271 int init_width = qs_.GetScaledResolution().width; 270 int init_width = qs_.GetScaledResolution().width;
272 int init_height = qs_.GetScaledResolution().height; 271 int init_height = qs_.GetScaledResolution().height;
273 EXPECT_EQ(640, init_width); 272 EXPECT_EQ(640, init_width);
274 EXPECT_EQ(360, init_height); 273 EXPECT_EQ(360, init_height);
275 } 274 }
276 275
277 TEST_F(QualityScalerTest, DownscaleToQvgaOnLowerInitialBitrate) { 276 TEST_F(QualityScalerTest, DownscaleToQvgaOnLowerInitialBitrate) {
278 static const int kWidth720p = 1280; 277 static const int kWidth720p = 1280;
279 static const int kHeight720p = 720; 278 static const int kHeight720p = 720;
280 static const int kInitialBitrateKbps = 200; 279 static const int kInitialBitrateKbps = 200;
281 input_frame_.CreateEmptyFrame(kWidth720p, kHeight720p, kWidth720p, 280 input_frame_ = rtc::scoped_refptr<VideoFrameBuffer>(
282 kWidth720p / 2, kWidth720p / 2); 281 new rtc::RefCountedObject<I420Buffer>(kWidth720p, kHeight720p));
283 qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, kInitialBitrateKbps, 282 qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, kInitialBitrateKbps,
284 kWidth720p, kHeight720p, kFramerate); 283 kWidth720p, kHeight720p, kFramerate);
285 qs_.OnEncodeFrame(input_frame_); 284 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
286 int init_width = qs_.GetScaledResolution().width; 285 int init_width = qs_.GetScaledResolution().width;
287 int init_height = qs_.GetScaledResolution().height; 286 int init_height = qs_.GetScaledResolution().height;
288 EXPECT_EQ(320, init_width); 287 EXPECT_EQ(320, init_width);
289 EXPECT_EQ(180, init_height); 288 EXPECT_EQ(180, init_height);
290 } 289 }
291 290
292 TEST_F(QualityScalerTest, DownscaleAfterMeasuredSecondsThenSlowerBackUp) { 291 TEST_F(QualityScalerTest, DownscaleAfterMeasuredSecondsThenSlowerBackUp) {
293 qs_.Init(kLowQpThreshold, kHighQp, 0, kWidth, kHeight, kFramerate); 292 qs_.Init(kLowQpThreshold, kHighQp, 0, kWidth, kHeight, kFramerate);
294 qs_.OnEncodeFrame(input_frame_); 293 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
295 QualityScaler::Resolution initial_res = qs_.GetScaledResolution(); 294 QualityScaler::Resolution initial_res = qs_.GetScaledResolution();
296 295
297 // Should not downscale if less than kMeasureSecondsDownscale seconds passed. 296 // Should not downscale if less than kMeasureSecondsDownscale seconds passed.
298 for (int i = 0; i < kFramerate * kMeasureSecondsDownscale - 1; ++i) { 297 for (int i = 0; i < kFramerate * kMeasureSecondsDownscale - 1; ++i) {
299 qs_.ReportQP(kHighQp + 1); 298 qs_.ReportQP(kHighQp + 1);
300 qs_.OnEncodeFrame(input_frame_); 299 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
301 } 300 }
302 EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width); 301 EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width);
303 EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height); 302 EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height);
304 303
305 // Should downscale if more than kMeasureSecondsDownscale seconds passed (add 304 // Should downscale if more than kMeasureSecondsDownscale seconds passed (add
306 // last frame). 305 // last frame).
307 qs_.ReportQP(kHighQp + 1); 306 qs_.ReportQP(kHighQp + 1);
308 qs_.OnEncodeFrame(input_frame_); 307 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
309 EXPECT_GT(initial_res.width, qs_.GetScaledResolution().width); 308 EXPECT_GT(initial_res.width, qs_.GetScaledResolution().width);
310 EXPECT_GT(initial_res.height, qs_.GetScaledResolution().height); 309 EXPECT_GT(initial_res.height, qs_.GetScaledResolution().height);
311 310
312 // Should not upscale if less than kMeasureSecondsUpscale seconds passed since 311 // Should not upscale if less than kMeasureSecondsUpscale seconds passed since
313 // we saw issues initially (have already gone down). 312 // we saw issues initially (have already gone down).
314 for (int i = 0; i < kFramerate * kMeasureSecondsUpscale - 1; ++i) { 313 for (int i = 0; i < kFramerate * kMeasureSecondsUpscale - 1; ++i) {
315 qs_.ReportQP(kLowQp); 314 qs_.ReportQP(kLowQp);
316 qs_.OnEncodeFrame(input_frame_); 315 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
317 } 316 }
318 EXPECT_GT(initial_res.width, qs_.GetScaledResolution().width); 317 EXPECT_GT(initial_res.width, qs_.GetScaledResolution().width);
319 EXPECT_GT(initial_res.height, qs_.GetScaledResolution().height); 318 EXPECT_GT(initial_res.height, qs_.GetScaledResolution().height);
320 319
321 // Should upscale (back to initial) if kMeasureSecondsUpscale seconds passed 320 // Should upscale (back to initial) if kMeasureSecondsUpscale seconds passed
322 // (add last frame). 321 // (add last frame).
323 qs_.ReportQP(kLowQp); 322 qs_.ReportQP(kLowQp);
324 qs_.OnEncodeFrame(input_frame_); 323 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
325 EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width); 324 EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width);
326 EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height); 325 EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height);
327 } 326 }
328 327
329 TEST_F(QualityScalerTest, UpscaleQuicklyInitiallyAfterMeasuredSeconds) { 328 TEST_F(QualityScalerTest, UpscaleQuicklyInitiallyAfterMeasuredSeconds) {
330 qs_.Init(kLowQpThreshold, kHighQp, kLowInitialBitrateKbps, kWidth, kHeight, 329 qs_.Init(kLowQpThreshold, kHighQp, kLowInitialBitrateKbps, kWidth, kHeight,
331 kFramerate); 330 kFramerate);
332 qs_.OnEncodeFrame(input_frame_); 331 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
333 QualityScaler::Resolution initial_res = qs_.GetScaledResolution(); 332 QualityScaler::Resolution initial_res = qs_.GetScaledResolution();
334 333
335 // Should not upscale if less than kMeasureSecondsFastUpscale seconds passed. 334 // Should not upscale if less than kMeasureSecondsFastUpscale seconds passed.
336 for (int i = 0; i < kFramerate * kMeasureSecondsFastUpscale - 1; ++i) { 335 for (int i = 0; i < kFramerate * kMeasureSecondsFastUpscale - 1; ++i) {
337 qs_.ReportQP(kLowQp); 336 qs_.ReportQP(kLowQp);
338 qs_.OnEncodeFrame(input_frame_); 337 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
339 } 338 }
340 EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width); 339 EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width);
341 EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height); 340 EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height);
342 341
343 // Should upscale if kMeasureSecondsFastUpscale seconds passed (add last 342 // Should upscale if kMeasureSecondsFastUpscale seconds passed (add last
344 // frame). 343 // frame).
345 qs_.ReportQP(kLowQp); 344 qs_.ReportQP(kLowQp);
346 qs_.OnEncodeFrame(input_frame_); 345 qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
347 EXPECT_LT(initial_res.width, qs_.GetScaledResolution().width); 346 EXPECT_LT(initial_res.width, qs_.GetScaledResolution().width);
348 EXPECT_LT(initial_res.height, qs_.GetScaledResolution().height); 347 EXPECT_LT(initial_res.height, qs_.GetScaledResolution().height);
349 } 348 }
350 349
351 void QualityScalerTest::DownscaleEndsAt(int input_width, 350 void QualityScalerTest::DownscaleEndsAt(int input_width,
352 int input_height, 351 int input_height,
353 int end_width, 352 int end_width,
354 int end_height) { 353 int end_height) {
355 // Create a frame with 2x expected end width/height to verify that we can 354 // Create a frame with 2x expected end width/height to verify that we can
356 // scale down to expected end width/height. 355 // scale down to expected end width/height.
357 input_frame_.CreateEmptyFrame(input_width, input_height, input_width, 356 input_frame_ = rtc::scoped_refptr<VideoFrameBuffer>(
358 (input_width + 1) / 2, (input_width + 1) / 2); 357 new rtc::RefCountedObject<I420Buffer>(input_width, input_height));
359 358
360 int last_width = input_width; 359 int last_width = input_width;
361 int last_height = input_height; 360 int last_height = input_height;
362 // Drop all frames to force-trigger downscaling. 361 // Drop all frames to force-trigger downscaling.
363 while (true) { 362 while (true) {
364 TriggerScale(kScaleDown); 363 TriggerScale(kScaleDown);
365 QualityScaler::Resolution res = qs_.GetScaledResolution(); 364 QualityScaler::Resolution res = qs_.GetScaledResolution();
366 if (last_width == res.width) { 365 if (last_width == res.width) {
367 EXPECT_EQ(last_height, res.height); 366 EXPECT_EQ(last_height, res.height);
368 EXPECT_EQ(end_width, res.width); 367 EXPECT_EQ(end_width, res.width);
(...skipping 15 matching lines...) Expand all
384 383
385 TEST_F(QualityScalerTest, DownscalesFrom1280x720To320x180) { 384 TEST_F(QualityScalerTest, DownscalesFrom1280x720To320x180) {
386 DownscaleEndsAt(1280, 720, 320, 180); 385 DownscaleEndsAt(1280, 720, 320, 180);
387 } 386 }
388 387
389 TEST_F(QualityScalerTest, DoesntDownscaleInitialQvga) { 388 TEST_F(QualityScalerTest, DoesntDownscaleInitialQvga) {
390 DownscaleEndsAt(320, 180, 320, 180); 389 DownscaleEndsAt(320, 180, 320, 180);
391 } 390 }
392 391
393 } // namespace webrtc 392 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/utility/quality_scaler.cc ('k') | webrtc/modules/video_processing/spatial_resampler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698