blob: 347e24d9057d6716b9f572c3f34ef085aae8dfa1 [file] [log] [blame]
buildbot@webrtc.org4f0d4012014-08-07 04:47:361/*
kjellander1afca732016-02-08 04:46:452 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved.
buildbot@webrtc.org4f0d4012014-08-07 04:47:363 *
kjellander1afca732016-02-08 04:46:454 * 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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
buildbot@webrtc.org4f0d4012014-08-07 04:47:369 */
10
Jonas Olssona4d87372019-07-05 17:08:3311#include "media/base/video_adapter.h"
12
Steve Antone78bcb92017-10-31 16:53:0813#include <limits>
kwibergbfefb032016-05-01 21:53:4614#include <memory>
Åsa Persson3f7e0ed2019-10-18 13:03:1315#include <string>
Åsa Persson2e4419e2018-09-06 13:02:5516#include <utility>
buildbot@webrtc.org4f0d4012014-08-07 04:47:3617
Yves Gerey3e707812018-11-28 15:47:4918#include "api/video/video_frame.h"
Rasmus Brandt287e4642019-11-15 15:56:0119#include "api/video/video_source_interface.h"
Steve Anton10542f22019-01-11 17:11:0020#include "media/base/fake_frame_source.h"
Åsa Persson3f7e0ed2019-10-18 13:03:1321#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 17:11:0022#include "rtc_base/time_utils.h"
Åsa Persson3f7e0ed2019-10-18 13:03:1323#include "test/field_trial.h"
Yves Gerey3e707812018-11-28 15:47:4924#include "test/gtest.h"
buildbot@webrtc.org4f0d4012014-08-07 04:47:3625
26namespace cricket {
sprangc5d62e22017-04-03 06:53:0427namespace {
Niels Möllera6cc0f92018-02-12 16:14:5528const int kWidth = 1280;
29const int kHeight = 720;
sprangc5d62e22017-04-03 06:53:0430const int kDefaultFps = 30;
Rasmus Brandt287e4642019-11-15 15:56:0131
32rtc::VideoSinkWants BuildSinkWants(absl::optional<int> target_pixel_count,
33 int max_pixel_count,
Rasmus Brandt5cad55b2019-12-19 08:47:1134 int max_framerate_fps,
35 int sink_alignment = 1) {
Rasmus Brandt287e4642019-11-15 15:56:0136 rtc::VideoSinkWants wants;
37 wants.target_pixel_count = target_pixel_count;
38 wants.max_pixel_count = max_pixel_count;
39 wants.max_framerate_fps = max_framerate_fps;
Rasmus Brandt5cad55b2019-12-19 08:47:1140 wants.resolution_alignment = sink_alignment;
Rasmus Brandt287e4642019-11-15 15:56:0141 return wants;
42}
43
sprangc5d62e22017-04-03 06:53:0444} // namespace
buildbot@webrtc.org4f0d4012014-08-07 04:47:3645
Mirko Bonadei6a489f22019-04-09 13:11:1246class VideoAdapterTest : public ::testing::Test,
Åsa Persson2e4419e2018-09-06 13:02:5547 public ::testing::WithParamInterface<bool> {
buildbot@webrtc.org4f0d4012014-08-07 04:47:3648 public:
Rasmus Brandt5cad55b2019-12-19 08:47:1149 VideoAdapterTest() : VideoAdapterTest("", 1) {}
50 explicit VideoAdapterTest(const std::string& field_trials,
51 int source_resolution_alignment)
Åsa Persson3f7e0ed2019-10-18 13:03:1352 : override_field_trials_(field_trials),
53 frame_source_(std::make_unique<FakeFrameSource>(
Åsa Persson2e4419e2018-09-06 13:02:5554 kWidth,
55 kHeight,
56 VideoFormat::FpsToInterval(kDefaultFps) /
57 rtc::kNumNanosecsPerMicrosec)),
Rasmus Brandt5cad55b2019-12-19 08:47:1158 adapter_(source_resolution_alignment),
Mirko Bonadei317a1f02019-09-17 15:06:1859 adapter_wrapper_(std::make_unique<VideoAdapterWrapper>(&adapter_)),
Åsa Persson2e4419e2018-09-06 13:02:5560 use_new_format_request_(GetParam()) {}
pbos@webrtc.org75c3ec12014-08-27 18:16:1361
buildbot@webrtc.org4f0d4012014-08-07 04:47:3662 protected:
Niels Möllera6cc0f92018-02-12 16:14:5563 // Wrap a VideoAdapter and collect stats.
64 class VideoAdapterWrapper {
buildbot@webrtc.org4f0d4012014-08-07 04:47:3665 public:
pbos@webrtc.orgc9b3f77e2014-08-26 12:33:1866 struct Stats {
Åsa Persson2e4419e2018-09-06 13:02:5567 int captured_frames = 0;
68 int dropped_frames = 0;
69 bool last_adapt_was_no_op = false;
pbos@webrtc.orgc9b3f77e2014-08-26 12:33:1870
Åsa Persson2e4419e2018-09-06 13:02:5571 int cropped_width = 0;
72 int cropped_height = 0;
73 int out_width = 0;
74 int out_height = 0;
pbos@webrtc.orgc9b3f77e2014-08-26 12:33:1875 };
76
Niels Möllera6cc0f92018-02-12 16:14:5577 explicit VideoAdapterWrapper(VideoAdapter* adapter)
Åsa Persson2e4419e2018-09-06 13:02:5578 : video_adapter_(adapter) {}
buildbot@webrtc.org4f0d4012014-08-07 04:47:3679
Niels Möllera6cc0f92018-02-12 16:14:5580 void AdaptFrame(const webrtc::VideoFrame& frame) {
nissef5297a02016-09-30 08:34:2781 const int in_width = frame.width();
82 const int in_height = frame.height();
magjed709f73c2016-05-13 17:26:0083 int cropped_width;
84 int cropped_height;
85 int out_width;
86 int out_height;
nissef5297a02016-09-30 08:34:2787 if (video_adapter_->AdaptFrameResolution(
88 in_width, in_height,
89 frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec,
90 &cropped_width, &cropped_height, &out_width, &out_height)) {
Åsa Persson2e4419e2018-09-06 13:02:5591 stats_.cropped_width = cropped_width;
92 stats_.cropped_height = cropped_height;
93 stats_.out_width = out_width;
94 stats_.out_height = out_height;
95 stats_.last_adapt_was_no_op =
magjed709f73c2016-05-13 17:26:0096 (in_width == cropped_width && in_height == cropped_height &&
97 in_width == out_width && in_height == out_height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:3698 } else {
Åsa Persson2e4419e2018-09-06 13:02:5599 ++stats_.dropped_frames;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36100 }
Åsa Persson2e4419e2018-09-06 13:02:55101 ++stats_.captured_frames;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36102 }
103
Åsa Persson2e4419e2018-09-06 13:02:55104 Stats GetStats() const { return stats_; }
pbos@webrtc.orgc9b3f77e2014-08-26 12:33:18105
buildbot@webrtc.org4f0d4012014-08-07 04:47:36106 private:
107 VideoAdapter* video_adapter_;
Åsa Persson2e4419e2018-09-06 13:02:55108 Stats stats_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36109 };
110
Niels Möllera6cc0f92018-02-12 16:14:55111 void VerifyAdaptedResolution(const VideoAdapterWrapper::Stats& stats,
magjed709f73c2016-05-13 17:26:00112 int cropped_width,
113 int cropped_height,
114 int out_width,
115 int out_height) {
116 EXPECT_EQ(cropped_width, stats.cropped_width);
117 EXPECT_EQ(cropped_height, stats.cropped_height);
118 EXPECT_EQ(out_width, stats.out_width);
119 EXPECT_EQ(out_height, stats.out_height);
pbos@webrtc.orgc9b3f77e2014-08-26 12:33:18120 }
121
Åsa Persson2e4419e2018-09-06 13:02:55122 void OnOutputFormatRequest(int width,
123 int height,
124 const absl::optional<int>& fps) {
125 if (use_new_format_request_) {
126 absl::optional<std::pair<int, int>> target_aspect_ratio =
127 std::make_pair(width, height);
128 absl::optional<int> max_pixel_count = width * height;
129 absl::optional<int> max_fps = fps;
130 adapter_.OnOutputFormatRequest(target_aspect_ratio, max_pixel_count,
131 max_fps);
132 return;
133 }
134 adapter_.OnOutputFormatRequest(
135 VideoFormat(width, height, fps ? VideoFormat::FpsToInterval(*fps) : 0,
136 cricket::FOURCC_I420));
137 }
138
Åsa Persson3f7e0ed2019-10-18 13:03:13139 webrtc::test::ScopedFieldTrials override_field_trials_;
Åsa Persson2e4419e2018-09-06 13:02:55140 const std::unique_ptr<FakeFrameSource> frame_source_;
Per766ad3b92016-04-05 13:23:49141 VideoAdapter adapter_;
magjed709f73c2016-05-13 17:26:00142 int cropped_width_;
143 int cropped_height_;
144 int out_width_;
145 int out_height_;
Åsa Persson2e4419e2018-09-06 13:02:55146 const std::unique_ptr<VideoAdapterWrapper> adapter_wrapper_;
147 const bool use_new_format_request_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36148};
149
Åsa Persson3f7e0ed2019-10-18 13:03:13150class VideoAdapterTestVariableStartScale : public VideoAdapterTest {
151 public:
152 VideoAdapterTestVariableStartScale()
Rasmus Brandt5cad55b2019-12-19 08:47:11153 : VideoAdapterTest("WebRTC-Video-VariableStartScaleFactor/Enabled/",
154 /*source_resolution_alignment=*/1) {}
Åsa Persson3f7e0ed2019-10-18 13:03:13155};
156
Mirko Bonadeic84f6612019-01-31 11:20:57157INSTANTIATE_TEST_SUITE_P(OnOutputFormatRequests,
158 VideoAdapterTest,
159 ::testing::Values(true, false));
Åsa Persson2e4419e2018-09-06 13:02:55160
Åsa Persson3f7e0ed2019-10-18 13:03:13161INSTANTIATE_TEST_SUITE_P(OnOutputFormatRequests,
162 VideoAdapterTestVariableStartScale,
163 ::testing::Values(true, false));
164
magjed709f73c2016-05-13 17:26:00165// Do not adapt the frame rate or the resolution. Expect no frame drop, no
166// cropping, and no resolution change.
Åsa Persson2e4419e2018-09-06 13:02:55167TEST_P(VideoAdapterTest, AdaptNothing) {
Magnus Jedvert01840572015-04-10 09:18:39168 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55169 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36170
171 // Verify no frame drop and no resolution change.
Niels Möllera6cc0f92018-02-12 16:14:55172 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
pbos@webrtc.orgc9b3f77e2014-08-26 12:33:18173 EXPECT_GE(stats.captured_frames, 10);
174 EXPECT_EQ(0, stats.dropped_frames);
Åsa Persson2e4419e2018-09-06 13:02:55175 VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
pbos@webrtc.orgc9b3f77e2014-08-26 12:33:18176 EXPECT_TRUE(stats.last_adapt_was_no_op);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36177}
178
Åsa Persson2e4419e2018-09-06 13:02:55179TEST_P(VideoAdapterTest, AdaptZeroInterval) {
180 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);
181 for (int i = 0; i < 40; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55182 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36183
184 // Verify no crash and that frames aren't dropped.
Niels Möllera6cc0f92018-02-12 16:14:55185 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
Åsa Persson2e4419e2018-09-06 13:02:55186 EXPECT_GE(stats.captured_frames, 40);
pbos@webrtc.orgc9b3f77e2014-08-26 12:33:18187 EXPECT_EQ(0, stats.dropped_frames);
Åsa Persson2e4419e2018-09-06 13:02:55188 VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36189}
190
191// Adapt the frame rate to be half of the capture rate at the beginning. Expect
192// the number of dropped frames to be half of the number the captured frames.
Åsa Persson2e4419e2018-09-06 13:02:55193TEST_P(VideoAdapterTest, AdaptFramerateToHalf) {
194 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps / 2);
magjed604abe02016-05-19 13:05:40195
196 // Capture 10 frames and verify that every other frame is dropped. The first
197 // frame should not be dropped.
Åsa Persson062acd92021-08-16 07:33:13198 for (int i = 0; i < 10; ++i)
199 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
Niels Möllera6cc0f92018-02-12 16:14:55200 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 10);
201 EXPECT_EQ(5, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 13:05:40202}
203
204// Adapt the frame rate to be two thirds of the capture rate at the beginning.
205// Expect the number of dropped frames to be one thirds of the number the
206// captured frames.
Åsa Persson2e4419e2018-09-06 13:02:55207TEST_P(VideoAdapterTest, AdaptFramerateToTwoThirds) {
208 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps * 2 / 3);
magjed604abe02016-05-19 13:05:40209
210 // Capture 10 frames and verify that every third frame is dropped. The first
211 // frame should not be dropped.
Åsa Persson062acd92021-08-16 07:33:13212 for (int i = 0; i < 10; ++i)
213 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
Niels Möllera6cc0f92018-02-12 16:14:55214 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 10);
215 EXPECT_EQ(3, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 13:05:40216}
217
218// Request frame rate twice as high as captured frame rate. Expect no frame
219// drop.
Åsa Persson2e4419e2018-09-06 13:02:55220TEST_P(VideoAdapterTest, AdaptFramerateHighLimit) {
221 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps * 2);
222
Magnus Jedvert01840572015-04-10 09:18:39223 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55224 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36225
magjed604abe02016-05-19 13:05:40226 // Verify no frame drop.
Niels Möllera6cc0f92018-02-12 16:14:55227 EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36228}
229
Åsa Persson2e4419e2018-09-06 13:02:55230// Adapt the frame rate to be half of the capture rate. No resolution limit set.
231// Expect the number of dropped frames to be half of the number the captured
232// frames.
233TEST_P(VideoAdapterTest, AdaptFramerateToHalfWithNoPixelLimit) {
234 adapter_.OnOutputFormatRequest(absl::nullopt, absl::nullopt, kDefaultFps / 2);
235
236 // Capture 10 frames and verify that every other frame is dropped. The first
237 // frame should not be dropped.
238 int expected_dropped_frames = 0;
239 for (int i = 0; i < 10; ++i) {
240 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
241 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, i + 1);
242 if (i % 2 == 1)
243 ++expected_dropped_frames;
244 EXPECT_EQ(expected_dropped_frames,
245 adapter_wrapper_->GetStats().dropped_frames);
246 VerifyAdaptedResolution(adapter_wrapper_->GetStats(), kWidth, kHeight,
247 kWidth, kHeight);
248 }
249}
250
buildbot@webrtc.org4f0d4012014-08-07 04:47:36251// Adapt the frame rate to be half of the capture rate after capturing no less
252// than 10 frames. Expect no frame dropped before adaptation and frame dropped
253// after adaptation.
Åsa Persson2e4419e2018-09-06 13:02:55254TEST_P(VideoAdapterTest, AdaptFramerateOntheFly) {
255 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps);
Magnus Jedvert01840572015-04-10 09:18:39256 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55257 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36258
259 // Verify no frame drop before adaptation.
Niels Möllera6cc0f92018-02-12 16:14:55260 EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36261
Åsa Persson2e4419e2018-09-06 13:02:55262 // Adapt the frame rate.
263 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps / 2);
Magnus Jedvert01840572015-04-10 09:18:39264 for (int i = 0; i < 20; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55265 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36266
267 // Verify frame drop after adaptation.
Niels Möllera6cc0f92018-02-12 16:14:55268 EXPECT_GT(adapter_wrapper_->GetStats().dropped_frames, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36269}
270
sprangc5d62e22017-04-03 06:53:04271// Do not adapt the frame rate or the resolution. Expect no frame drop, no
272// cropping, and no resolution change.
Åsa Persson2e4419e2018-09-06 13:02:55273TEST_P(VideoAdapterTest, AdaptFramerateRequestMax) {
Rasmus Brandt287e4642019-11-15 15:56:01274 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
275 std::numeric_limits<int>::max(),
276 std::numeric_limits<int>::max()));
sprangc5d62e22017-04-03 06:53:04277
sprangc5d62e22017-04-03 06:53:04278 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55279 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
sprangc5d62e22017-04-03 06:53:04280
281 // Verify no frame drop and no resolution change.
Niels Möllera6cc0f92018-02-12 16:14:55282 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
sprangc5d62e22017-04-03 06:53:04283 EXPECT_GE(stats.captured_frames, 10);
284 EXPECT_EQ(0, stats.dropped_frames);
Åsa Persson2e4419e2018-09-06 13:02:55285 VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
sprangc5d62e22017-04-03 06:53:04286 EXPECT_TRUE(stats.last_adapt_was_no_op);
287}
288
Åsa Persson2e4419e2018-09-06 13:02:55289TEST_P(VideoAdapterTest, AdaptFramerateRequestZero) {
Rasmus Brandt287e4642019-11-15 15:56:01290 adapter_.OnSinkWants(
291 BuildSinkWants(absl::nullopt, std::numeric_limits<int>::max(), 0));
sprangc5d62e22017-04-03 06:53:04292 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55293 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
sprangc5d62e22017-04-03 06:53:04294
295 // Verify no crash and that frames aren't dropped.
Niels Möllera6cc0f92018-02-12 16:14:55296 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
sprangc5d62e22017-04-03 06:53:04297 EXPECT_GE(stats.captured_frames, 10);
298 EXPECT_EQ(10, stats.dropped_frames);
299}
300
301// Adapt the frame rate to be half of the capture rate at the beginning. Expect
302// the number of dropped frames to be half of the number the captured frames.
Åsa Persson2e4419e2018-09-06 13:02:55303TEST_P(VideoAdapterTest, AdaptFramerateRequestHalf) {
Rasmus Brandt287e4642019-11-15 15:56:01304 adapter_.OnSinkWants(BuildSinkWants(
305 absl::nullopt, std::numeric_limits<int>::max(), kDefaultFps / 2));
sprangc5d62e22017-04-03 06:53:04306 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55307 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
sprangc5d62e22017-04-03 06:53:04308
309 // Verify no crash and that frames aren't dropped.
Niels Möllera6cc0f92018-02-12 16:14:55310 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
sprangc5d62e22017-04-03 06:53:04311 EXPECT_GE(stats.captured_frames, 10);
312 EXPECT_EQ(5, stats.dropped_frames);
Åsa Persson2e4419e2018-09-06 13:02:55313 VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
sprangc5d62e22017-04-03 06:53:04314}
315
magjed709f73c2016-05-13 17:26:00316// Set a very high output pixel resolution. Expect no cropping or resolution
317// change.
Åsa Persson2e4419e2018-09-06 13:02:55318TEST_P(VideoAdapterTest, AdaptFrameResolutionHighLimit) {
319 OnOutputFormatRequest(kWidth * 10, kHeight * 10, kDefaultFps);
320 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0, &cropped_width_,
321 &cropped_height_, &out_width_,
322 &out_height_));
323 EXPECT_EQ(kWidth, cropped_width_);
324 EXPECT_EQ(kHeight, cropped_height_);
325 EXPECT_EQ(kWidth, out_width_);
326 EXPECT_EQ(kHeight, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14327}
328
329// Adapt the frame resolution to be the same as capture resolution. Expect no
magjed709f73c2016-05-13 17:26:00330// cropping or resolution change.
Åsa Persson2e4419e2018-09-06 13:02:55331TEST_P(VideoAdapterTest, AdaptFrameResolutionIdentical) {
332 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps);
333 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0, &cropped_width_,
334 &cropped_height_, &out_width_,
335 &out_height_));
336 EXPECT_EQ(kWidth, cropped_width_);
337 EXPECT_EQ(kHeight, cropped_height_);
338 EXPECT_EQ(kWidth, out_width_);
339 EXPECT_EQ(kHeight, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14340}
341
342// Adapt the frame resolution to be a quarter of the capture resolution. Expect
magjed709f73c2016-05-13 17:26:00343// no cropping, but a resolution change.
Åsa Persson2e4419e2018-09-06 13:02:55344TEST_P(VideoAdapterTest, AdaptFrameResolutionQuarter) {
345 OnOutputFormatRequest(kWidth / 2, kHeight / 2, kDefaultFps);
346 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0, &cropped_width_,
347 &cropped_height_, &out_width_,
348 &out_height_));
349 EXPECT_EQ(kWidth, cropped_width_);
350 EXPECT_EQ(kHeight, cropped_height_);
351 EXPECT_EQ(kWidth / 2, out_width_);
352 EXPECT_EQ(kHeight / 2, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14353}
354
355// Adapt the pixel resolution to 0. Expect frame drop.
Åsa Persson2e4419e2018-09-06 13:02:55356TEST_P(VideoAdapterTest, AdaptFrameResolutionDrop) {
357 OnOutputFormatRequest(kWidth * 0, kHeight * 0, kDefaultFps);
358 EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
359 &cropped_width_, &cropped_height_,
360 &out_width_, &out_height_));
magjed@webrtc.orgf58b4552014-11-19 18:09:14361}
362
buildbot@webrtc.org4f0d4012014-08-07 04:47:36363// Adapt the frame resolution to be a quarter of the capture resolution at the
magjed709f73c2016-05-13 17:26:00364// beginning. Expect no cropping but a resolution change.
Åsa Persson2e4419e2018-09-06 13:02:55365TEST_P(VideoAdapterTest, AdaptResolution) {
366 OnOutputFormatRequest(kWidth / 2, kHeight / 2, kDefaultFps);
Magnus Jedvert01840572015-04-10 09:18:39367 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55368 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36369
magjed709f73c2016-05-13 17:26:00370 // Verify no frame drop, no cropping, and resolution change.
Niels Möllera6cc0f92018-02-12 16:14:55371 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
pbos@webrtc.orgc9b3f77e2014-08-26 12:33:18372 EXPECT_EQ(0, stats.dropped_frames);
Åsa Persson2e4419e2018-09-06 13:02:55373 VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth / 2, kHeight / 2);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36374}
375
buildbot@webrtc.org4f0d4012014-08-07 04:47:36376// Adapt the frame resolution to be a quarter of the capture resolution after
377// capturing no less than 10 frames. Expect no resolution change before
378// adaptation and resolution change after adaptation.
Åsa Persson2e4419e2018-09-06 13:02:55379TEST_P(VideoAdapterTest, AdaptResolutionOnTheFly) {
380 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps);
Magnus Jedvert01840572015-04-10 09:18:39381 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55382 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36383
384 // Verify no resolution change before adaptation.
Åsa Persson2e4419e2018-09-06 13:02:55385 VerifyAdaptedResolution(adapter_wrapper_->GetStats(), kWidth, kHeight, kWidth,
386 kHeight);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36387
388 // Adapt the frame resolution.
Åsa Persson2e4419e2018-09-06 13:02:55389 OnOutputFormatRequest(kWidth / 2, kHeight / 2, kDefaultFps);
Magnus Jedvert01840572015-04-10 09:18:39390 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55391 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36392
393 // Verify resolution change after adaptation.
Åsa Persson2e4419e2018-09-06 13:02:55394 VerifyAdaptedResolution(adapter_wrapper_->GetStats(), kWidth, kHeight,
395 kWidth / 2, kHeight / 2);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36396}
397
Åsa Persson2e4419e2018-09-06 13:02:55398// Drop all frames for resolution 0x0.
399TEST_P(VideoAdapterTest, DropAllFrames) {
400 OnOutputFormatRequest(kWidth * 0, kHeight * 0, kDefaultFps);
Magnus Jedvert01840572015-04-10 09:18:39401 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 16:14:55402 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36403
404 // Verify all frames are dropped.
Niels Möllera6cc0f92018-02-12 16:14:55405 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
pbos@webrtc.orgc9b3f77e2014-08-26 12:33:18406 EXPECT_GE(stats.captured_frames, 10);
407 EXPECT_EQ(stats.captured_frames, stats.dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36408}
409
Åsa Persson2e4419e2018-09-06 13:02:55410TEST_P(VideoAdapterTest, TestOnOutputFormatRequest) {
Jonas Olssona4d87372019-07-05 17:08:33411 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
412 &cropped_height_, &out_width_,
413 &out_height_));
magjed709f73c2016-05-13 17:26:00414 EXPECT_EQ(640, cropped_width_);
415 EXPECT_EQ(400, cropped_height_);
416 EXPECT_EQ(640, out_width_);
417 EXPECT_EQ(400, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36418
Per766ad3b92016-04-05 13:23:49419 // Format request 640x400.
Åsa Persson2e4419e2018-09-06 13:02:55420 OnOutputFormatRequest(640, 400, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33421 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
422 &cropped_height_, &out_width_,
423 &out_height_));
magjed709f73c2016-05-13 17:26:00424 EXPECT_EQ(640, cropped_width_);
425 EXPECT_EQ(400, cropped_height_);
426 EXPECT_EQ(640, out_width_);
427 EXPECT_EQ(400, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36428
magjed709f73c2016-05-13 17:26:00429 // Request 1280x720, higher than input, but aspect 16:9. Expect cropping but
430 // no scaling.
Åsa Persson2e4419e2018-09-06 13:02:55431 OnOutputFormatRequest(1280, 720, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33432 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
433 &cropped_height_, &out_width_,
434 &out_height_));
magjed709f73c2016-05-13 17:26:00435 EXPECT_EQ(640, cropped_width_);
436 EXPECT_EQ(360, cropped_height_);
437 EXPECT_EQ(640, out_width_);
438 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36439
Per766ad3b92016-04-05 13:23:49440 // Request 0x0.
Åsa Persson2e4419e2018-09-06 13:02:55441 OnOutputFormatRequest(0, 0, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33442 EXPECT_FALSE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
443 &cropped_height_, &out_width_,
444 &out_height_));
buildbot@webrtc.org4f0d4012014-08-07 04:47:36445
magjed709f73c2016-05-13 17:26:00446 // Request 320x200. Expect scaling, but no cropping.
Åsa Persson2e4419e2018-09-06 13:02:55447 OnOutputFormatRequest(320, 200, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33448 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
449 &cropped_height_, &out_width_,
450 &out_height_));
magjed709f73c2016-05-13 17:26:00451 EXPECT_EQ(640, cropped_width_);
452 EXPECT_EQ(400, cropped_height_);
453 EXPECT_EQ(320, out_width_);
454 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36455
magjed709f73c2016-05-13 17:26:00456 // Request resolution close to 2/3 scale. Expect adapt down. Scaling to 2/3
457 // is not optimized and not allowed, therefore 1/2 scaling will be used
458 // instead.
Åsa Persson2e4419e2018-09-06 13:02:55459 OnOutputFormatRequest(424, 265, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33460 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
461 &cropped_height_, &out_width_,
462 &out_height_));
magjed709f73c2016-05-13 17:26:00463 EXPECT_EQ(640, cropped_width_);
464 EXPECT_EQ(400, cropped_height_);
465 EXPECT_EQ(320, out_width_);
466 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36467
Per766ad3b92016-04-05 13:23:49468 // Request resolution of 3 / 8. Expect adapt down.
Åsa Persson2e4419e2018-09-06 13:02:55469 OnOutputFormatRequest(640 * 3 / 8, 400 * 3 / 8, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33470 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
471 &cropped_height_, &out_width_,
472 &out_height_));
magjed709f73c2016-05-13 17:26:00473 EXPECT_EQ(640, cropped_width_);
474 EXPECT_EQ(400, cropped_height_);
475 EXPECT_EQ(640 * 3 / 8, out_width_);
476 EXPECT_EQ(400 * 3 / 8, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36477
Per766ad3b92016-04-05 13:23:49478 // Switch back up. Expect adapt.
Åsa Persson2e4419e2018-09-06 13:02:55479 OnOutputFormatRequest(320, 200, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33480 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
481 &cropped_height_, &out_width_,
482 &out_height_));
magjed709f73c2016-05-13 17:26:00483 EXPECT_EQ(640, cropped_width_);
484 EXPECT_EQ(400, cropped_height_);
485 EXPECT_EQ(320, out_width_);
486 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36487
Per766ad3b92016-04-05 13:23:49488 // Format request 480x300.
Åsa Persson2e4419e2018-09-06 13:02:55489 OnOutputFormatRequest(480, 300, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33490 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
491 &cropped_height_, &out_width_,
492 &out_height_));
magjed709f73c2016-05-13 17:26:00493 EXPECT_EQ(640, cropped_width_);
494 EXPECT_EQ(400, cropped_height_);
495 EXPECT_EQ(480, out_width_);
496 EXPECT_EQ(300, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36497}
498
Åsa Persson2e4419e2018-09-06 13:02:55499TEST_P(VideoAdapterTest, TestViewRequestPlusCameraSwitch) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36500 // Start at HD.
Jonas Olssona4d87372019-07-05 17:08:33501 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
502 &cropped_height_, &out_width_,
503 &out_height_));
magjed709f73c2016-05-13 17:26:00504 EXPECT_EQ(1280, cropped_width_);
505 EXPECT_EQ(720, cropped_height_);
506 EXPECT_EQ(1280, out_width_);
507 EXPECT_EQ(720, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36508
Per766ad3b92016-04-05 13:23:49509 // Format request for VGA.
Åsa Persson2e4419e2018-09-06 13:02:55510 OnOutputFormatRequest(640, 360, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33511 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
512 &cropped_height_, &out_width_,
513 &out_height_));
magjed709f73c2016-05-13 17:26:00514 EXPECT_EQ(1280, cropped_width_);
515 EXPECT_EQ(720, cropped_height_);
516 EXPECT_EQ(640, out_width_);
517 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36518
519 // Now, the camera reopens at VGA.
520 // Both the frame and the output format should be 640x360.
Jonas Olssona4d87372019-07-05 17:08:33521 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
522 &cropped_height_, &out_width_,
523 &out_height_));
magjed709f73c2016-05-13 17:26:00524 EXPECT_EQ(640, cropped_width_);
525 EXPECT_EQ(360, cropped_height_);
526 EXPECT_EQ(640, out_width_);
527 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36528
529 // And another view request comes in for 640x360, which should have no
530 // real impact.
Åsa Persson2e4419e2018-09-06 13:02:55531 OnOutputFormatRequest(640, 360, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33532 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
533 &cropped_height_, &out_width_,
534 &out_height_));
magjed709f73c2016-05-13 17:26:00535 EXPECT_EQ(640, cropped_width_);
536 EXPECT_EQ(360, cropped_height_);
537 EXPECT_EQ(640, out_width_);
538 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36539}
540
Åsa Persson2e4419e2018-09-06 13:02:55541TEST_P(VideoAdapterTest, TestVgaWidth) {
Rasmus Brandt5cad55b2019-12-19 08:47:11542 // Requested output format is 640x360.
Åsa Persson2e4419e2018-09-06 13:02:55543 OnOutputFormatRequest(640, 360, absl::nullopt);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36544
Jonas Olssona4d87372019-07-05 17:08:33545 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
546 &cropped_height_, &out_width_,
547 &out_height_));
magjed709f73c2016-05-13 17:26:00548 // Expect cropping.
549 EXPECT_EQ(640, cropped_width_);
550 EXPECT_EQ(360, cropped_height_);
551 EXPECT_EQ(640, out_width_);
552 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36553
554 // But if frames come in at 640x360, we shouldn't adapt them down.
Jonas Olssona4d87372019-07-05 17:08:33555 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
556 &cropped_height_, &out_width_,
557 &out_height_));
magjed709f73c2016-05-13 17:26:00558 EXPECT_EQ(640, cropped_width_);
559 EXPECT_EQ(360, cropped_height_);
560 EXPECT_EQ(640, out_width_);
561 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36562
Jonas Olssona4d87372019-07-05 17:08:33563 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
564 &cropped_height_, &out_width_,
565 &out_height_));
magjed709f73c2016-05-13 17:26:00566 EXPECT_EQ(640, cropped_width_);
567 EXPECT_EQ(360, cropped_height_);
568 EXPECT_EQ(640, out_width_);
569 EXPECT_EQ(360, out_height_);
Per766ad3b92016-04-05 13:23:49570}
buildbot@webrtc.org4f0d4012014-08-07 04:47:36571
Åsa Persson2e4419e2018-09-06 13:02:55572TEST_P(VideoAdapterTest, TestOnResolutionRequestInSmallSteps) {
Jonas Olssona4d87372019-07-05 17:08:33573 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
574 &cropped_height_, &out_width_,
575 &out_height_));
magjed709f73c2016-05-13 17:26:00576 EXPECT_EQ(1280, cropped_width_);
577 EXPECT_EQ(720, cropped_height_);
578 EXPECT_EQ(1280, out_width_);
579 EXPECT_EQ(720, out_height_);
Per766ad3b92016-04-05 13:23:49580
581 // Adapt down one step.
Rasmus Brandt287e4642019-11-15 15:56:01582 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 1280 * 720 - 1,
583 std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33584 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
585 &cropped_height_, &out_width_,
586 &out_height_));
magjed709f73c2016-05-13 17:26:00587 EXPECT_EQ(1280, cropped_width_);
588 EXPECT_EQ(720, cropped_height_);
589 EXPECT_EQ(960, out_width_);
590 EXPECT_EQ(540, out_height_);
Per766ad3b92016-04-05 13:23:49591
592 // Adapt down one step more.
Rasmus Brandt287e4642019-11-15 15:56:01593 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 960 * 540 - 1,
594 std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33595 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
596 &cropped_height_, &out_width_,
597 &out_height_));
magjed709f73c2016-05-13 17:26:00598 EXPECT_EQ(1280, cropped_width_);
599 EXPECT_EQ(720, cropped_height_);
600 EXPECT_EQ(640, out_width_);
601 EXPECT_EQ(360, out_height_);
Per766ad3b92016-04-05 13:23:49602
603 // Adapt down one step more.
Rasmus Brandt287e4642019-11-15 15:56:01604 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
605 std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33606 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
607 &cropped_height_, &out_width_,
608 &out_height_));
magjed709f73c2016-05-13 17:26:00609 EXPECT_EQ(1280, cropped_width_);
610 EXPECT_EQ(720, cropped_height_);
611 EXPECT_EQ(480, out_width_);
612 EXPECT_EQ(270, out_height_);
Per766ad3b92016-04-05 13:23:49613
614 // Adapt up one step.
Rasmus Brandt287e4642019-11-15 15:56:01615 adapter_.OnSinkWants(
616 BuildSinkWants(640 * 360, 960 * 540, std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33617 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
618 &cropped_height_, &out_width_,
619 &out_height_));
magjed709f73c2016-05-13 17:26:00620 EXPECT_EQ(1280, cropped_width_);
621 EXPECT_EQ(720, cropped_height_);
622 EXPECT_EQ(640, out_width_);
623 EXPECT_EQ(360, out_height_);
Per766ad3b92016-04-05 13:23:49624
625 // Adapt up one step more.
Rasmus Brandt287e4642019-11-15 15:56:01626 adapter_.OnSinkWants(
627 BuildSinkWants(960 * 540, 1280 * 720, std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33628 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
629 &cropped_height_, &out_width_,
630 &out_height_));
magjed709f73c2016-05-13 17:26:00631 EXPECT_EQ(1280, cropped_width_);
632 EXPECT_EQ(720, cropped_height_);
633 EXPECT_EQ(960, out_width_);
634 EXPECT_EQ(540, out_height_);
Per766ad3b92016-04-05 13:23:49635
636 // Adapt up one step more.
Rasmus Brandt287e4642019-11-15 15:56:01637 adapter_.OnSinkWants(
638 BuildSinkWants(1280 * 720, 1920 * 1080, std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33639 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
640 &cropped_height_, &out_width_,
641 &out_height_));
magjed709f73c2016-05-13 17:26:00642 EXPECT_EQ(1280, cropped_width_);
643 EXPECT_EQ(720, cropped_height_);
644 EXPECT_EQ(1280, out_width_);
645 EXPECT_EQ(720, out_height_);
Per766ad3b92016-04-05 13:23:49646}
647
Åsa Persson2e4419e2018-09-06 13:02:55648TEST_P(VideoAdapterTest, TestOnResolutionRequestMaxZero) {
Jonas Olssona4d87372019-07-05 17:08:33649 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
650 &cropped_height_, &out_width_,
651 &out_height_));
magjed709f73c2016-05-13 17:26:00652 EXPECT_EQ(1280, cropped_width_);
653 EXPECT_EQ(720, cropped_height_);
654 EXPECT_EQ(1280, out_width_);
655 EXPECT_EQ(720, out_height_);
Per766ad3b92016-04-05 13:23:49656
Rasmus Brandt287e4642019-11-15 15:56:01657 adapter_.OnSinkWants(
658 BuildSinkWants(absl::nullopt, 0, std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33659 EXPECT_FALSE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
660 &cropped_height_, &out_width_,
661 &out_height_));
Per766ad3b92016-04-05 13:23:49662}
663
Åsa Persson2e4419e2018-09-06 13:02:55664TEST_P(VideoAdapterTest, TestOnResolutionRequestInLargeSteps) {
sprang84a37592017-02-10 15:04:27665 // Large step down.
Rasmus Brandt287e4642019-11-15 15:56:01666 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
667 std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33668 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
669 &cropped_height_, &out_width_,
670 &out_height_));
magjed709f73c2016-05-13 17:26:00671 EXPECT_EQ(1280, cropped_width_);
672 EXPECT_EQ(720, cropped_height_);
673 EXPECT_EQ(480, out_width_);
674 EXPECT_EQ(270, out_height_);
Per766ad3b92016-04-05 13:23:49675
sprang84a37592017-02-10 15:04:27676 // Large step up.
Rasmus Brandt287e4642019-11-15 15:56:01677 adapter_.OnSinkWants(
678 BuildSinkWants(1280 * 720, 1920 * 1080, std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33679 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
680 &cropped_height_, &out_width_,
681 &out_height_));
magjed709f73c2016-05-13 17:26:00682 EXPECT_EQ(1280, cropped_width_);
683 EXPECT_EQ(720, cropped_height_);
684 EXPECT_EQ(1280, out_width_);
685 EXPECT_EQ(720, out_height_);
Per766ad3b92016-04-05 13:23:49686}
687
Åsa Persson2e4419e2018-09-06 13:02:55688TEST_P(VideoAdapterTest, TestOnOutputFormatRequestCapsMaxResolution) {
Rasmus Brandt287e4642019-11-15 15:56:01689 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
690 std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33691 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
692 &cropped_height_, &out_width_,
693 &out_height_));
magjed709f73c2016-05-13 17:26:00694 EXPECT_EQ(1280, cropped_width_);
695 EXPECT_EQ(720, cropped_height_);
696 EXPECT_EQ(480, out_width_);
697 EXPECT_EQ(270, out_height_);
Per766ad3b92016-04-05 13:23:49698
Åsa Persson2e4419e2018-09-06 13:02:55699 OnOutputFormatRequest(640, 360, absl::nullopt);
Jonas Olssona4d87372019-07-05 17:08:33700 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
701 &cropped_height_, &out_width_,
702 &out_height_));
magjed709f73c2016-05-13 17:26:00703 EXPECT_EQ(1280, cropped_width_);
704 EXPECT_EQ(720, cropped_height_);
705 EXPECT_EQ(480, out_width_);
706 EXPECT_EQ(270, out_height_);
Per766ad3b92016-04-05 13:23:49707
Rasmus Brandt287e4642019-11-15 15:56:01708 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 960 * 720,
709 std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33710 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
711 &cropped_height_, &out_width_,
712 &out_height_));
magjed709f73c2016-05-13 17:26:00713 EXPECT_EQ(1280, cropped_width_);
714 EXPECT_EQ(720, cropped_height_);
715 EXPECT_EQ(640, out_width_);
716 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36717}
718
Åsa Persson2e4419e2018-09-06 13:02:55719TEST_P(VideoAdapterTest, TestOnResolutionRequestReset) {
Jonas Olssona4d87372019-07-05 17:08:33720 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
721 &cropped_height_, &out_width_,
722 &out_height_));
magjed709f73c2016-05-13 17:26:00723 EXPECT_EQ(1280, cropped_width_);
724 EXPECT_EQ(720, cropped_height_);
725 EXPECT_EQ(1280, out_width_);
726 EXPECT_EQ(720, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36727
Rasmus Brandt287e4642019-11-15 15:56:01728 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
729 std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33730 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
731 &cropped_height_, &out_width_,
732 &out_height_));
magjed709f73c2016-05-13 17:26:00733 EXPECT_EQ(1280, cropped_width_);
734 EXPECT_EQ(720, cropped_height_);
735 EXPECT_EQ(480, out_width_);
736 EXPECT_EQ(270, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36737
Rasmus Brandt287e4642019-11-15 15:56:01738 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
739 std::numeric_limits<int>::max(),
740 std::numeric_limits<int>::max()));
Jonas Olssona4d87372019-07-05 17:08:33741 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
742 &cropped_height_, &out_width_,
743 &out_height_));
magjed709f73c2016-05-13 17:26:00744 EXPECT_EQ(1280, cropped_width_);
745 EXPECT_EQ(720, cropped_height_);
746 EXPECT_EQ(1280, out_width_);
747 EXPECT_EQ(720, out_height_);
748}
749
Åsa Persson2e4419e2018-09-06 13:02:55750TEST_P(VideoAdapterTest, TestOnOutputFormatRequestResolutionReset) {
751 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
752 &cropped_height_, &out_width_,
753 &out_height_));
754 EXPECT_EQ(1280, cropped_width_);
755 EXPECT_EQ(720, cropped_height_);
756 EXPECT_EQ(1280, out_width_);
757 EXPECT_EQ(720, out_height_);
758
759 adapter_.OnOutputFormatRequest(absl::nullopt, 640 * 360 - 1, absl::nullopt);
760 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
761 &cropped_height_, &out_width_,
762 &out_height_));
763 EXPECT_EQ(1280, cropped_width_);
764 EXPECT_EQ(720, cropped_height_);
765 EXPECT_EQ(480, out_width_);
766 EXPECT_EQ(270, out_height_);
767
768 adapter_.OnOutputFormatRequest(absl::nullopt, absl::nullopt, absl::nullopt);
769 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
770 &cropped_height_, &out_width_,
771 &out_height_));
772 EXPECT_EQ(1280, cropped_width_);
773 EXPECT_EQ(720, cropped_height_);
774 EXPECT_EQ(1280, out_width_);
775 EXPECT_EQ(720, out_height_);
776}
777
778TEST_P(VideoAdapterTest, TestOnOutputFormatRequestFpsReset) {
779 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps / 2);
780 for (int i = 0; i < 10; ++i)
781 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
782
783 // Verify frame drop.
784 const int dropped_frames = adapter_wrapper_->GetStats().dropped_frames;
785 EXPECT_GT(dropped_frames, 0);
786
787 // Reset frame rate.
788 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);
789 for (int i = 0; i < 20; ++i)
790 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
791
792 // Verify no frame drop after reset.
793 EXPECT_EQ(dropped_frames, adapter_wrapper_->GetStats().dropped_frames);
794}
795
796TEST_P(VideoAdapterTest, RequestAspectRatio) {
797 // Request aspect ratio 320/180 (16:9), smaller than input, but no resolution
798 // limit. Expect cropping but no scaling.
799 adapter_.OnOutputFormatRequest(std::make_pair(320, 180), absl::nullopt,
800 absl::nullopt);
801 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
802 &cropped_height_, &out_width_,
803 &out_height_));
804 EXPECT_EQ(640, cropped_width_);
805 EXPECT_EQ(360, cropped_height_);
806 EXPECT_EQ(640, out_width_);
807 EXPECT_EQ(360, out_height_);
808}
809
810TEST_P(VideoAdapterTest, RequestAspectRatioWithDifferentOrientation) {
811 // Request 720x1280, higher than input, but aspect 16:9. Orientation should
812 // not matter, expect cropping but no scaling.
813 OnOutputFormatRequest(720, 1280, absl::nullopt);
814 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
815 &cropped_height_, &out_width_,
816 &out_height_));
817 EXPECT_EQ(640, cropped_width_);
818 EXPECT_EQ(360, cropped_height_);
819 EXPECT_EQ(640, out_width_);
820 EXPECT_EQ(360, out_height_);
821}
822
823TEST_P(VideoAdapterTest, InvalidAspectRatioIgnored) {
824 // Request aspect ratio 320/0. Expect no cropping.
825 adapter_.OnOutputFormatRequest(std::make_pair(320, 0), absl::nullopt,
826 absl::nullopt);
827 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
828 &cropped_height_, &out_width_,
829 &out_height_));
830 EXPECT_EQ(640, cropped_width_);
831 EXPECT_EQ(400, cropped_height_);
832 EXPECT_EQ(640, out_width_);
833 EXPECT_EQ(400, out_height_);
834}
835
836TEST_P(VideoAdapterTest, TestCroppingWithResolutionRequest) {
magjed709f73c2016-05-13 17:26:00837 // Ask for 640x360 (16:9 aspect).
Åsa Persson2e4419e2018-09-06 13:02:55838 OnOutputFormatRequest(640, 360, absl::nullopt);
magjed709f73c2016-05-13 17:26:00839 // Send 640x480 (4:3 aspect).
Jonas Olssona4d87372019-07-05 17:08:33840 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
841 &cropped_height_, &out_width_,
842 &out_height_));
magjed709f73c2016-05-13 17:26:00843 // Expect cropping to 16:9 format and no scaling.
844 EXPECT_EQ(640, cropped_width_);
845 EXPECT_EQ(360, cropped_height_);
846 EXPECT_EQ(640, out_width_);
847 EXPECT_EQ(360, out_height_);
848
849 // Adapt down one step.
Rasmus Brandt287e4642019-11-15 15:56:01850 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
851 std::numeric_limits<int>::max()));
magjed709f73c2016-05-13 17:26:00852 // Expect cropping to 16:9 format and 3/4 scaling.
Jonas Olssona4d87372019-07-05 17:08:33853 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
854 &cropped_height_, &out_width_,
855 &out_height_));
magjed709f73c2016-05-13 17:26:00856 EXPECT_EQ(640, cropped_width_);
857 EXPECT_EQ(360, cropped_height_);
858 EXPECT_EQ(480, out_width_);
859 EXPECT_EQ(270, out_height_);
860
861 // Adapt down one step more.
Rasmus Brandt287e4642019-11-15 15:56:01862 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 480 * 270 - 1,
863 std::numeric_limits<int>::max()));
magjed709f73c2016-05-13 17:26:00864 // Expect cropping to 16:9 format and 1/2 scaling.
Jonas Olssona4d87372019-07-05 17:08:33865 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
866 &cropped_height_, &out_width_,
867 &out_height_));
magjed709f73c2016-05-13 17:26:00868 EXPECT_EQ(640, cropped_width_);
869 EXPECT_EQ(360, cropped_height_);
870 EXPECT_EQ(320, out_width_);
871 EXPECT_EQ(180, out_height_);
872
873 // Adapt up one step.
Rasmus Brandt287e4642019-11-15 15:56:01874 adapter_.OnSinkWants(
875 BuildSinkWants(480 * 270, 640 * 360, std::numeric_limits<int>::max()));
magjed709f73c2016-05-13 17:26:00876 // Expect cropping to 16:9 format and 3/4 scaling.
Jonas Olssona4d87372019-07-05 17:08:33877 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
878 &cropped_height_, &out_width_,
879 &out_height_));
magjed709f73c2016-05-13 17:26:00880 EXPECT_EQ(640, cropped_width_);
881 EXPECT_EQ(360, cropped_height_);
882 EXPECT_EQ(480, out_width_);
883 EXPECT_EQ(270, out_height_);
884
885 // Adapt up one step more.
Rasmus Brandt287e4642019-11-15 15:56:01886 adapter_.OnSinkWants(
887 BuildSinkWants(640 * 360, 960 * 540, std::numeric_limits<int>::max()));
magjed709f73c2016-05-13 17:26:00888 // Expect cropping to 16:9 format and no scaling.
Jonas Olssona4d87372019-07-05 17:08:33889 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
890 &cropped_height_, &out_width_,
891 &out_height_));
magjed709f73c2016-05-13 17:26:00892 EXPECT_EQ(640, cropped_width_);
893 EXPECT_EQ(360, cropped_height_);
894 EXPECT_EQ(640, out_width_);
895 EXPECT_EQ(360, out_height_);
896
897 // Try to adapt up one step more.
Rasmus Brandt287e4642019-11-15 15:56:01898 adapter_.OnSinkWants(
899 BuildSinkWants(960 * 540, 1280 * 720, std::numeric_limits<int>::max()));
magjed709f73c2016-05-13 17:26:00900 // Expect cropping to 16:9 format and no scaling.
Jonas Olssona4d87372019-07-05 17:08:33901 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
902 &cropped_height_, &out_width_,
903 &out_height_));
magjed709f73c2016-05-13 17:26:00904 EXPECT_EQ(640, cropped_width_);
905 EXPECT_EQ(360, cropped_height_);
906 EXPECT_EQ(640, out_width_);
907 EXPECT_EQ(360, out_height_);
908}
909
Åsa Persson2e4419e2018-09-06 13:02:55910TEST_P(VideoAdapterTest, TestCroppingOddResolution) {
magjed709f73c2016-05-13 17:26:00911 // Ask for 640x360 (16:9 aspect), with 3/16 scaling.
Åsa Persson2e4419e2018-09-06 13:02:55912 OnOutputFormatRequest(640, 360, absl::nullopt);
Rasmus Brandt287e4642019-11-15 15:56:01913 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
914 640 * 360 * 3 / 16 * 3 / 16,
915 std::numeric_limits<int>::max()));
magjed709f73c2016-05-13 17:26:00916
917 // Send 640x480 (4:3 aspect).
Jonas Olssona4d87372019-07-05 17:08:33918 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
919 &cropped_height_, &out_width_,
920 &out_height_));
magjed709f73c2016-05-13 17:26:00921
922 // Instead of getting the exact aspect ratio with cropped resolution 640x360,
923 // the resolution should be adjusted to get a perfect scale factor instead.
924 EXPECT_EQ(640, cropped_width_);
925 EXPECT_EQ(368, cropped_height_);
926 EXPECT_EQ(120, out_width_);
927 EXPECT_EQ(69, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36928}
929
Åsa Persson2e4419e2018-09-06 13:02:55930TEST_P(VideoAdapterTest, TestAdaptToVerySmallResolution) {
kthelgasonc8474172016-12-08 16:04:51931 // Ask for 1920x1080 (16:9 aspect), with 1/16 scaling.
932 const int w = 1920;
933 const int h = 1080;
Åsa Persson2e4419e2018-09-06 13:02:55934 OnOutputFormatRequest(w, h, absl::nullopt);
Rasmus Brandt287e4642019-11-15 15:56:01935 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, w * h * 1 / 16 * 1 / 16,
936 std::numeric_limits<int>::max()));
kthelgasonc8474172016-12-08 16:04:51937
938 // Send 1920x1080 (16:9 aspect).
939 EXPECT_TRUE(adapter_.AdaptFrameResolution(
940 w, h, 0, &cropped_width_, &cropped_height_, &out_width_, &out_height_));
941
942 // Instead of getting the exact aspect ratio with cropped resolution 1920x1080
943 // the resolution should be adjusted to get a perfect scale factor instead.
944 EXPECT_EQ(1920, cropped_width_);
945 EXPECT_EQ(1072, cropped_height_);
946 EXPECT_EQ(120, out_width_);
947 EXPECT_EQ(67, out_height_);
948
949 // Adapt back up one step to 3/32.
Rasmus Brandt287e4642019-11-15 15:56:01950 adapter_.OnSinkWants(BuildSinkWants(w * h * 3 / 32 * 3 / 32,
951 w * h * 1 / 8 * 1 / 8,
952 std::numeric_limits<int>::max()));
kthelgasonc8474172016-12-08 16:04:51953
954 // Send 1920x1080 (16:9 aspect).
955 EXPECT_TRUE(adapter_.AdaptFrameResolution(
956 w, h, 0, &cropped_width_, &cropped_height_, &out_width_, &out_height_));
957
958 EXPECT_EQ(180, out_width_);
959 EXPECT_EQ(99, out_height_);
960}
961
Åsa Persson2e4419e2018-09-06 13:02:55962TEST_P(VideoAdapterTest, AdaptFrameResolutionDropWithResolutionRequest) {
963 OnOutputFormatRequest(0, 0, kDefaultFps);
964 EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
965 &cropped_width_, &cropped_height_,
966 &out_width_, &out_height_));
kthelgasonc8474172016-12-08 16:04:51967
Rasmus Brandt287e4642019-11-15 15:56:01968 adapter_.OnSinkWants(BuildSinkWants(960 * 540,
969 std::numeric_limits<int>::max(),
970 std::numeric_limits<int>::max()));
kthelgasonc8474172016-12-08 16:04:51971
972 // Still expect all frames to be dropped
Åsa Persson2e4419e2018-09-06 13:02:55973 EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
974 &cropped_width_, &cropped_height_,
975 &out_width_, &out_height_));
kthelgasonc8474172016-12-08 16:04:51976
Rasmus Brandt287e4642019-11-15 15:56:01977 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 480 - 1,
978 std::numeric_limits<int>::max()));
kthelgasonc8474172016-12-08 16:04:51979
980 // Still expect all frames to be dropped
Åsa Persson2e4419e2018-09-06 13:02:55981 EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
982 &cropped_width_, &cropped_height_,
983 &out_width_, &out_height_));
kthelgasonc8474172016-12-08 16:04:51984}
985
Magnus Jedvert6d230d72017-02-22 17:30:27986// Test that we will adapt to max given a target pixel count close to max.
Åsa Persson2e4419e2018-09-06 13:02:55987TEST_P(VideoAdapterTest, TestAdaptToMax) {
988 OnOutputFormatRequest(640, 360, kDefaultFps);
Rasmus Brandt287e4642019-11-15 15:56:01989 adapter_.OnSinkWants(BuildSinkWants(640 * 360 - 1 /* target */,
990 std::numeric_limits<int>::max(),
991 std::numeric_limits<int>::max()));
Magnus Jedvert6d230d72017-02-22 17:30:27992
993 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
994 &cropped_height_, &out_width_,
995 &out_height_));
996 EXPECT_EQ(640, out_width_);
997 EXPECT_EQ(360, out_height_);
998}
Magnus Jedvert06aa2092018-10-26 12:00:18999
1000// Test adjusting to 16:9 in landscape, and 9:16 in portrait.
1001TEST(VideoAdapterTestMultipleOrientation, TestNormal) {
1002 VideoAdapter video_adapter;
1003 video_adapter.OnOutputFormatRequest(std::make_pair(640, 360), 640 * 360,
1004 std::make_pair(360, 640), 360 * 640, 30);
1005
1006 int cropped_width;
1007 int cropped_height;
1008 int out_width;
1009 int out_height;
1010 EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1011 /* in_width= */ 640, /* in_height= */ 480, /* in_timestamp_ns= */ 0,
1012 &cropped_width, &cropped_height, &out_width, &out_height));
1013 EXPECT_EQ(640, cropped_width);
1014 EXPECT_EQ(360, cropped_height);
1015 EXPECT_EQ(640, out_width);
1016 EXPECT_EQ(360, out_height);
1017
1018 EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1019 /* in_width= */ 480, /* in_height= */ 640,
1020 /* in_timestamp_ns= */ rtc::kNumNanosecsPerSec / 30, &cropped_width,
1021 &cropped_height, &out_width, &out_height));
1022 EXPECT_EQ(360, cropped_width);
1023 EXPECT_EQ(640, cropped_height);
1024 EXPECT_EQ(360, out_width);
1025 EXPECT_EQ(640, out_height);
1026}
1027
1028// Force output to be 9:16, even for landscape input.
1029TEST(VideoAdapterTestMultipleOrientation, TestForcePortrait) {
1030 VideoAdapter video_adapter;
1031 video_adapter.OnOutputFormatRequest(std::make_pair(360, 640), 640 * 360,
1032 std::make_pair(360, 640), 360 * 640, 30);
1033
1034 int cropped_width;
1035 int cropped_height;
1036 int out_width;
1037 int out_height;
1038 EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1039 /* in_width= */ 640, /* in_height= */ 480, /* in_timestamp_ns= */ 0,
1040 &cropped_width, &cropped_height, &out_width, &out_height));
1041 EXPECT_EQ(270, cropped_width);
1042 EXPECT_EQ(480, cropped_height);
1043 EXPECT_EQ(270, out_width);
1044 EXPECT_EQ(480, out_height);
1045
1046 EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1047 /* in_width= */ 480, /* in_height= */ 640,
1048 /* in_timestamp_ns= */ rtc::kNumNanosecsPerSec / 30, &cropped_width,
1049 &cropped_height, &out_width, &out_height));
1050 EXPECT_EQ(360, cropped_width);
1051 EXPECT_EQ(640, cropped_height);
1052 EXPECT_EQ(360, out_width);
1053 EXPECT_EQ(640, out_height);
1054}
1055
Åsa Persson3f7e0ed2019-10-18 13:03:131056TEST_P(VideoAdapterTest, AdaptResolutionInSteps) {
1057 const int kWidth = 1280;
1058 const int kHeight = 720;
1059 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt); // 16:9 aspect.
1060
1061 // Scale factors: 3/4, 2/3, 3/4, 2/3, ...
1062 // Scale : 3/4, 1/2, 3/8, 1/4, 3/16, 1/8.
1063 const int kExpectedWidths[] = {960, 640, 480, 320, 240, 160};
1064 const int kExpectedHeights[] = {540, 360, 270, 180, 135, 90};
1065
1066 int request_width = kWidth;
1067 int request_height = kHeight;
1068
1069 for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1070 // Adapt down one step.
Rasmus Brandt287e4642019-11-15 15:56:011071 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
1072 request_width * request_height - 1,
1073 std::numeric_limits<int>::max()));
Åsa Persson3f7e0ed2019-10-18 13:03:131074 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1075 &cropped_width_, &cropped_height_,
1076 &out_width_, &out_height_));
1077 EXPECT_EQ(kExpectedWidths[i], out_width_);
1078 EXPECT_EQ(kExpectedHeights[i], out_height_);
1079 request_width = out_width_;
1080 request_height = out_height_;
1081 }
1082}
1083
1084// Scale factors are 3/4, 2/3, 3/4, 2/3, ... (see test above).
1085// In VideoAdapterTestVariableStartScale, first scale factor depends on
1086// resolution. May start with:
1087// - 2/3 (if width/height multiple of 3) or
1088// - 2/3, 2/3 (if width/height multiple of 9).
1089TEST_P(VideoAdapterTestVariableStartScale, AdaptResolutionInStepsFirst3_4) {
1090 const int kWidth = 1280;
1091 const int kHeight = 720;
1092 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt); // 16:9 aspect.
1093
1094 // Scale factors: 3/4, 2/3, 3/4, 2/3, ...
1095 // Scale : 3/4, 1/2, 3/8, 1/4, 3/16, 1/8.
1096 const int kExpectedWidths[] = {960, 640, 480, 320, 240, 160};
1097 const int kExpectedHeights[] = {540, 360, 270, 180, 135, 90};
1098
1099 int request_width = kWidth;
1100 int request_height = kHeight;
1101
1102 for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1103 // Adapt down one step.
Rasmus Brandt287e4642019-11-15 15:56:011104 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
1105 request_width * request_height - 1,
1106 std::numeric_limits<int>::max()));
Åsa Persson3f7e0ed2019-10-18 13:03:131107 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1108 &cropped_width_, &cropped_height_,
1109 &out_width_, &out_height_));
1110 EXPECT_EQ(kExpectedWidths[i], out_width_);
1111 EXPECT_EQ(kExpectedHeights[i], out_height_);
1112 request_width = out_width_;
1113 request_height = out_height_;
1114 }
1115}
1116
1117TEST_P(VideoAdapterTestVariableStartScale, AdaptResolutionInStepsFirst2_3) {
1118 const int kWidth = 1920;
1119 const int kHeight = 1080;
1120 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt); // 16:9 aspect.
1121
1122 // Scale factors: 2/3, 3/4, 2/3, 3/4, ...
1123 // Scale: 2/3, 1/2, 1/3, 1/4, 1/6, 1/8, 1/12.
1124 const int kExpectedWidths[] = {1280, 960, 640, 480, 320, 240, 160};
1125 const int kExpectedHeights[] = {720, 540, 360, 270, 180, 135, 90};
1126
1127 int request_width = kWidth;
1128 int request_height = kHeight;
1129
1130 for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1131 // Adapt down one step.
Rasmus Brandt287e4642019-11-15 15:56:011132 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
1133 request_width * request_height - 1,
1134 std::numeric_limits<int>::max()));
Åsa Persson3f7e0ed2019-10-18 13:03:131135 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1136 &cropped_width_, &cropped_height_,
1137 &out_width_, &out_height_));
1138 EXPECT_EQ(kExpectedWidths[i], out_width_);
1139 EXPECT_EQ(kExpectedHeights[i], out_height_);
1140 request_width = out_width_;
1141 request_height = out_height_;
1142 }
1143}
1144
1145TEST_P(VideoAdapterTestVariableStartScale, AdaptResolutionInStepsFirst2x2_3) {
1146 const int kWidth = 1440;
1147 const int kHeight = 1080;
1148 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt); // 4:3 aspect.
1149
1150 // Scale factors: 2/3, 2/3, 3/4, 2/3, 3/4, ...
1151 // Scale : 2/3, 4/9, 1/3, 2/9, 1/6, 1/9, 1/12, 1/18, 1/24, 1/36.
1152 const int kExpectedWidths[] = {960, 640, 480, 320, 240, 160, 120, 80, 60, 40};
1153 const int kExpectedHeights[] = {720, 480, 360, 240, 180, 120, 90, 60, 45, 30};
1154
1155 int request_width = kWidth;
1156 int request_height = kHeight;
1157
1158 for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1159 // Adapt down one step.
Rasmus Brandt287e4642019-11-15 15:56:011160 adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
1161 request_width * request_height - 1,
1162 std::numeric_limits<int>::max()));
Åsa Persson3f7e0ed2019-10-18 13:03:131163 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1164 &cropped_width_, &cropped_height_,
1165 &out_width_, &out_height_));
1166 EXPECT_EQ(kExpectedWidths[i], out_width_);
1167 EXPECT_EQ(kExpectedHeights[i], out_height_);
1168 request_width = out_width_;
1169 request_height = out_height_;
1170 }
1171}
1172
Rasmus Brandt5cad55b2019-12-19 08:47:111173TEST_P(VideoAdapterTest, AdaptResolutionWithSinkAlignment) {
1174 constexpr int kSourceWidth = 1280;
1175 constexpr int kSourceHeight = 720;
1176 constexpr int kSourceFramerate = 30;
1177 constexpr int kRequestedWidth = 480;
1178 constexpr int kRequestedHeight = 270;
1179 constexpr int kRequestedFramerate = 30;
1180
1181 OnOutputFormatRequest(kRequestedWidth, kRequestedHeight, kRequestedFramerate);
1182
1183 int frame_num = 1;
1184 for (const int sink_alignment : {2, 3, 4, 5}) {
1185 adapter_.OnSinkWants(
1186 BuildSinkWants(absl::nullopt, std::numeric_limits<int>::max(),
1187 std::numeric_limits<int>::max(), sink_alignment));
1188 EXPECT_TRUE(adapter_.AdaptFrameResolution(
1189 kSourceWidth, kSourceHeight,
1190 frame_num * rtc::kNumNanosecsPerSec / kSourceFramerate, &cropped_width_,
1191 &cropped_height_, &out_width_, &out_height_));
1192 EXPECT_EQ(out_width_ % sink_alignment, 0);
1193 EXPECT_EQ(out_height_ % sink_alignment, 0);
1194
1195 ++frame_num;
1196 }
1197}
1198
1199class VideoAdapterWithSourceAlignmentTest : public VideoAdapterTest {
1200 protected:
1201 static constexpr int kSourceResolutionAlignment = 7;
1202
1203 VideoAdapterWithSourceAlignmentTest()
1204 : VideoAdapterTest(/*field_trials=*/"", kSourceResolutionAlignment) {}
1205};
1206
1207TEST_P(VideoAdapterWithSourceAlignmentTest, AdaptResolution) {
1208 constexpr int kSourceWidth = 1280;
1209 constexpr int kSourceHeight = 720;
1210 constexpr int kRequestedWidth = 480;
1211 constexpr int kRequestedHeight = 270;
1212 constexpr int kRequestedFramerate = 30;
1213
1214 OnOutputFormatRequest(kRequestedWidth, kRequestedHeight, kRequestedFramerate);
1215
1216 EXPECT_TRUE(adapter_.AdaptFrameResolution(
1217 kSourceWidth, kSourceHeight, /*in_timestamp_ns=*/0, &cropped_width_,
1218 &cropped_height_, &out_width_, &out_height_));
1219 EXPECT_EQ(out_width_ % kSourceResolutionAlignment, 0);
1220 EXPECT_EQ(out_height_ % kSourceResolutionAlignment, 0);
1221}
1222
1223TEST_P(VideoAdapterWithSourceAlignmentTest, AdaptResolutionWithSinkAlignment) {
1224 constexpr int kSourceWidth = 1280;
1225 constexpr int kSourceHeight = 720;
1226 // 7 and 8 neither divide 480 nor 270.
1227 constexpr int kRequestedWidth = 480;
1228 constexpr int kRequestedHeight = 270;
1229 constexpr int kRequestedFramerate = 30;
1230 constexpr int kSinkResolutionAlignment = 8;
1231
1232 OnOutputFormatRequest(kRequestedWidth, kRequestedHeight, kRequestedFramerate);
1233
1234 adapter_.OnSinkWants(BuildSinkWants(
1235 absl::nullopt, std::numeric_limits<int>::max(),
1236 std::numeric_limits<int>::max(), kSinkResolutionAlignment));
1237 EXPECT_TRUE(adapter_.AdaptFrameResolution(
1238 kSourceWidth, kSourceHeight, /*in_timestamp_ns=*/0, &cropped_width_,
1239 &cropped_height_, &out_width_, &out_height_));
1240 EXPECT_EQ(out_width_ % kSourceResolutionAlignment, 0);
1241 EXPECT_EQ(out_height_ % kSourceResolutionAlignment, 0);
1242 EXPECT_EQ(out_width_ % kSinkResolutionAlignment, 0);
1243 EXPECT_EQ(out_height_ % kSinkResolutionAlignment, 0);
1244}
1245
1246INSTANTIATE_TEST_SUITE_P(OnOutputFormatRequests,
1247 VideoAdapterWithSourceAlignmentTest,
1248 ::testing::Values(true, false));
1249
buildbot@webrtc.org4f0d4012014-08-07 04:47:361250} // namespace cricket