blob: 6529ee7713884415d4c5636c2c1ba3b542bf285b [file] [log] [blame]
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * 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:36 +00009 */
10
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "media/base/video_adapter.h"
12
Steve Antone78bcb92017-10-31 09:53:08 -070013#include <limits>
kwibergbfefb032016-05-01 14:53:46 -070014#include <memory>
Åsa Persson3f7e0ed2019-10-18 15:03:13 +020015#include <string>
Åsa Persson2e4419e2018-09-06 15:02:55 +020016#include <utility>
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000017
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "api/video/video_frame.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "media/base/fake_frame_source.h"
Åsa Persson3f7e0ed2019-10-18 15:03:13 +020020#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "rtc_base/time_utils.h"
Åsa Persson3f7e0ed2019-10-18 15:03:13 +020022#include "test/field_trial.h"
Yves Gerey3e707812018-11-28 16:47:49 +010023#include "test/gtest.h"
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000024
25namespace cricket {
sprangc5d62e22017-04-02 23:53:04 -070026namespace {
Niels Möllera6cc0f92018-02-12 17:14:55 +010027const int kWidth = 1280;
28const int kHeight = 720;
sprangc5d62e22017-04-02 23:53:04 -070029const int kDefaultFps = 30;
30} // namespace
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000031
Mirko Bonadei6a489f22019-04-09 15:11:12 +020032class VideoAdapterTest : public ::testing::Test,
Åsa Persson2e4419e2018-09-06 15:02:55 +020033 public ::testing::WithParamInterface<bool> {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000034 public:
Åsa Persson3f7e0ed2019-10-18 15:03:13 +020035 VideoAdapterTest() : VideoAdapterTest("") {}
36 explicit VideoAdapterTest(const std::string& field_trials)
37 : override_field_trials_(field_trials),
38 frame_source_(std::make_unique<FakeFrameSource>(
Åsa Persson2e4419e2018-09-06 15:02:55 +020039 kWidth,
40 kHeight,
41 VideoFormat::FpsToInterval(kDefaultFps) /
42 rtc::kNumNanosecsPerMicrosec)),
Mirko Bonadei317a1f02019-09-17 17:06:18 +020043 adapter_wrapper_(std::make_unique<VideoAdapterWrapper>(&adapter_)),
Åsa Persson2e4419e2018-09-06 15:02:55 +020044 use_new_format_request_(GetParam()) {}
pbos@webrtc.org75c3ec12014-08-27 18:16:13 +000045
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000046 protected:
Niels Möllera6cc0f92018-02-12 17:14:55 +010047 // Wrap a VideoAdapter and collect stats.
48 class VideoAdapterWrapper {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000049 public:
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000050 struct Stats {
Åsa Persson2e4419e2018-09-06 15:02:55 +020051 int captured_frames = 0;
52 int dropped_frames = 0;
53 bool last_adapt_was_no_op = false;
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000054
Åsa Persson2e4419e2018-09-06 15:02:55 +020055 int cropped_width = 0;
56 int cropped_height = 0;
57 int out_width = 0;
58 int out_height = 0;
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000059 };
60
Niels Möllera6cc0f92018-02-12 17:14:55 +010061 explicit VideoAdapterWrapper(VideoAdapter* adapter)
Åsa Persson2e4419e2018-09-06 15:02:55 +020062 : video_adapter_(adapter) {}
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000063
Niels Möllera6cc0f92018-02-12 17:14:55 +010064 void AdaptFrame(const webrtc::VideoFrame& frame) {
nissef5297a02016-09-30 01:34:27 -070065 const int in_width = frame.width();
66 const int in_height = frame.height();
magjed709f73c2016-05-13 10:26:00 -070067 int cropped_width;
68 int cropped_height;
69 int out_width;
70 int out_height;
nissef5297a02016-09-30 01:34:27 -070071 if (video_adapter_->AdaptFrameResolution(
72 in_width, in_height,
73 frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec,
74 &cropped_width, &cropped_height, &out_width, &out_height)) {
Åsa Persson2e4419e2018-09-06 15:02:55 +020075 stats_.cropped_width = cropped_width;
76 stats_.cropped_height = cropped_height;
77 stats_.out_width = out_width;
78 stats_.out_height = out_height;
79 stats_.last_adapt_was_no_op =
magjed709f73c2016-05-13 10:26:00 -070080 (in_width == cropped_width && in_height == cropped_height &&
81 in_width == out_width && in_height == out_height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000082 } else {
Åsa Persson2e4419e2018-09-06 15:02:55 +020083 ++stats_.dropped_frames;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000084 }
Åsa Persson2e4419e2018-09-06 15:02:55 +020085 ++stats_.captured_frames;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000086 }
87
Åsa Persson2e4419e2018-09-06 15:02:55 +020088 Stats GetStats() const { return stats_; }
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000089
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000090 private:
91 VideoAdapter* video_adapter_;
Åsa Persson2e4419e2018-09-06 15:02:55 +020092 Stats stats_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000093 };
94
Niels Möllera6cc0f92018-02-12 17:14:55 +010095 void VerifyAdaptedResolution(const VideoAdapterWrapper::Stats& stats,
magjed709f73c2016-05-13 10:26:00 -070096 int cropped_width,
97 int cropped_height,
98 int out_width,
99 int out_height) {
100 EXPECT_EQ(cropped_width, stats.cropped_width);
101 EXPECT_EQ(cropped_height, stats.cropped_height);
102 EXPECT_EQ(out_width, stats.out_width);
103 EXPECT_EQ(out_height, stats.out_height);
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000104 }
105
Åsa Persson2e4419e2018-09-06 15:02:55 +0200106 void OnOutputFormatRequest(int width,
107 int height,
108 const absl::optional<int>& fps) {
109 if (use_new_format_request_) {
110 absl::optional<std::pair<int, int>> target_aspect_ratio =
111 std::make_pair(width, height);
112 absl::optional<int> max_pixel_count = width * height;
113 absl::optional<int> max_fps = fps;
114 adapter_.OnOutputFormatRequest(target_aspect_ratio, max_pixel_count,
115 max_fps);
116 return;
117 }
118 adapter_.OnOutputFormatRequest(
119 VideoFormat(width, height, fps ? VideoFormat::FpsToInterval(*fps) : 0,
120 cricket::FOURCC_I420));
121 }
122
Åsa Persson3f7e0ed2019-10-18 15:03:13 +0200123 webrtc::test::ScopedFieldTrials override_field_trials_;
Åsa Persson2e4419e2018-09-06 15:02:55 +0200124 const std::unique_ptr<FakeFrameSource> frame_source_;
Per766ad3b2016-04-05 15:23:49 +0200125 VideoAdapter adapter_;
magjed709f73c2016-05-13 10:26:00 -0700126 int cropped_width_;
127 int cropped_height_;
128 int out_width_;
129 int out_height_;
Åsa Persson2e4419e2018-09-06 15:02:55 +0200130 const std::unique_ptr<VideoAdapterWrapper> adapter_wrapper_;
131 const bool use_new_format_request_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000132};
133
Åsa Persson3f7e0ed2019-10-18 15:03:13 +0200134class VideoAdapterTestVariableStartScale : public VideoAdapterTest {
135 public:
136 VideoAdapterTestVariableStartScale()
137 : VideoAdapterTest("WebRTC-Video-VariableStartScaleFactor/Enabled/") {}
138};
139
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100140INSTANTIATE_TEST_SUITE_P(OnOutputFormatRequests,
141 VideoAdapterTest,
142 ::testing::Values(true, false));
Åsa Persson2e4419e2018-09-06 15:02:55 +0200143
Åsa Persson3f7e0ed2019-10-18 15:03:13 +0200144INSTANTIATE_TEST_SUITE_P(OnOutputFormatRequests,
145 VideoAdapterTestVariableStartScale,
146 ::testing::Values(true, false));
147
magjed709f73c2016-05-13 10:26:00 -0700148// Do not adapt the frame rate or the resolution. Expect no frame drop, no
149// cropping, and no resolution change.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200150TEST_P(VideoAdapterTest, AdaptNothing) {
Magnus Jedvert01840572015-04-10 11:18:39 +0200151 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100152 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000153
154 // Verify no frame drop and no resolution change.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100155 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000156 EXPECT_GE(stats.captured_frames, 10);
157 EXPECT_EQ(0, stats.dropped_frames);
Åsa Persson2e4419e2018-09-06 15:02:55 +0200158 VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000159 EXPECT_TRUE(stats.last_adapt_was_no_op);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000160}
161
Åsa Persson2e4419e2018-09-06 15:02:55 +0200162TEST_P(VideoAdapterTest, AdaptZeroInterval) {
163 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);
164 for (int i = 0; i < 40; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100165 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000166
167 // Verify no crash and that frames aren't dropped.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100168 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
Åsa Persson2e4419e2018-09-06 15:02:55 +0200169 EXPECT_GE(stats.captured_frames, 40);
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000170 EXPECT_EQ(0, stats.dropped_frames);
Åsa Persson2e4419e2018-09-06 15:02:55 +0200171 VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000172}
173
174// Adapt the frame rate to be half of the capture rate at the beginning. Expect
175// the number of dropped frames to be half of the number the captured frames.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200176TEST_P(VideoAdapterTest, AdaptFramerateToHalf) {
177 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps / 2);
magjed604abe02016-05-19 06:05:40 -0700178
179 // Capture 10 frames and verify that every other frame is dropped. The first
180 // frame should not be dropped.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100181 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
182 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 1);
183 EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700184
Niels Möllera6cc0f92018-02-12 17:14:55 +0100185 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
186 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 2);
187 EXPECT_EQ(1, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700188
Niels Möllera6cc0f92018-02-12 17:14:55 +0100189 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
190 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 3);
191 EXPECT_EQ(1, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700192
Niels Möllera6cc0f92018-02-12 17:14:55 +0100193 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
194 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 4);
195 EXPECT_EQ(2, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700196
Niels Möllera6cc0f92018-02-12 17:14:55 +0100197 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
198 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 5);
199 EXPECT_EQ(2, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700200
Niels Möllera6cc0f92018-02-12 17:14:55 +0100201 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
202 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 6);
203 EXPECT_EQ(3, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700204
Niels Möllera6cc0f92018-02-12 17:14:55 +0100205 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
206 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 7);
207 EXPECT_EQ(3, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700208
Niels Möllera6cc0f92018-02-12 17:14:55 +0100209 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
210 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 8);
211 EXPECT_EQ(4, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700212
Niels Möllera6cc0f92018-02-12 17:14:55 +0100213 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
214 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 9);
215 EXPECT_EQ(4, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700216
Niels Möllera6cc0f92018-02-12 17:14:55 +0100217 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
218 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 10);
219 EXPECT_EQ(5, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700220}
221
222// Adapt the frame rate to be two thirds of the capture rate at the beginning.
223// Expect the number of dropped frames to be one thirds of the number the
224// captured frames.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200225TEST_P(VideoAdapterTest, AdaptFramerateToTwoThirds) {
226 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps * 2 / 3);
magjed604abe02016-05-19 06:05:40 -0700227
228 // Capture 10 frames and verify that every third frame is dropped. The first
229 // frame should not be dropped.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100230 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
231 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 1);
232 EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700233
Niels Möllera6cc0f92018-02-12 17:14:55 +0100234 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
235 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 2);
236 EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700237
Niels Möllera6cc0f92018-02-12 17:14:55 +0100238 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
239 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 3);
240 EXPECT_EQ(1, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700241
Niels Möllera6cc0f92018-02-12 17:14:55 +0100242 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
243 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 4);
244 EXPECT_EQ(1, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700245
Niels Möllera6cc0f92018-02-12 17:14:55 +0100246 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
247 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 5);
248 EXPECT_EQ(1, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700249
Niels Möllera6cc0f92018-02-12 17:14:55 +0100250 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
251 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 6);
252 EXPECT_EQ(2, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700253
Niels Möllera6cc0f92018-02-12 17:14:55 +0100254 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
255 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 7);
256 EXPECT_EQ(2, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700257
Niels Möllera6cc0f92018-02-12 17:14:55 +0100258 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
259 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 8);
260 EXPECT_EQ(2, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700261
Niels Möllera6cc0f92018-02-12 17:14:55 +0100262 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
263 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 9);
264 EXPECT_EQ(3, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700265
Niels Möllera6cc0f92018-02-12 17:14:55 +0100266 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
267 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 10);
268 EXPECT_EQ(3, adapter_wrapper_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700269}
270
271// Request frame rate twice as high as captured frame rate. Expect no frame
272// drop.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200273TEST_P(VideoAdapterTest, AdaptFramerateHighLimit) {
274 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps * 2);
275
Magnus Jedvert01840572015-04-10 11:18:39 +0200276 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100277 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000278
magjed604abe02016-05-19 06:05:40 -0700279 // Verify no frame drop.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100280 EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000281}
282
Åsa Persson2e4419e2018-09-06 15:02:55 +0200283// Adapt the frame rate to be half of the capture rate. No resolution limit set.
284// Expect the number of dropped frames to be half of the number the captured
285// frames.
286TEST_P(VideoAdapterTest, AdaptFramerateToHalfWithNoPixelLimit) {
287 adapter_.OnOutputFormatRequest(absl::nullopt, absl::nullopt, kDefaultFps / 2);
288
289 // Capture 10 frames and verify that every other frame is dropped. The first
290 // frame should not be dropped.
291 int expected_dropped_frames = 0;
292 for (int i = 0; i < 10; ++i) {
293 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
294 EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, i + 1);
295 if (i % 2 == 1)
296 ++expected_dropped_frames;
297 EXPECT_EQ(expected_dropped_frames,
298 adapter_wrapper_->GetStats().dropped_frames);
299 VerifyAdaptedResolution(adapter_wrapper_->GetStats(), kWidth, kHeight,
300 kWidth, kHeight);
301 }
302}
303
magjed604abe02016-05-19 06:05:40 -0700304// After the first timestamp, add a big offset to the timestamps. Expect that
305// the adapter is conservative and resets to the new offset and does not drop
306// any frame.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200307TEST_P(VideoAdapterTest, AdaptFramerateTimestampOffset) {
sprangc5d62e22017-04-02 23:53:04 -0700308 const int64_t capture_interval = VideoFormat::FpsToInterval(kDefaultFps);
Åsa Persson2e4419e2018-09-06 15:02:55 +0200309 OnOutputFormatRequest(640, 480, kDefaultFps);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000310
magjed604abe02016-05-19 06:05:40 -0700311 const int64_t first_timestamp = 0;
Jonas Olssona4d87372019-07-05 19:08:33 +0200312 adapter_.AdaptFrameResolution(640, 480, first_timestamp, &cropped_width_,
313 &cropped_height_, &out_width_, &out_height_);
magjed604abe02016-05-19 06:05:40 -0700314 EXPECT_GT(out_width_, 0);
315 EXPECT_GT(out_height_, 0);
316
317 const int64_t big_offset = -987654321LL * 1000;
318 const int64_t second_timestamp = big_offset;
Jonas Olssona4d87372019-07-05 19:08:33 +0200319 adapter_.AdaptFrameResolution(640, 480, second_timestamp, &cropped_width_,
320 &cropped_height_, &out_width_, &out_height_);
magjed604abe02016-05-19 06:05:40 -0700321 EXPECT_GT(out_width_, 0);
322 EXPECT_GT(out_height_, 0);
323
324 const int64_t third_timestamp = big_offset + capture_interval;
Jonas Olssona4d87372019-07-05 19:08:33 +0200325 adapter_.AdaptFrameResolution(640, 480, third_timestamp, &cropped_width_,
326 &cropped_height_, &out_width_, &out_height_);
magjed604abe02016-05-19 06:05:40 -0700327 EXPECT_GT(out_width_, 0);
328 EXPECT_GT(out_height_, 0);
329}
330
331// Request 30 fps and send 30 fps with jitter. Expect that no frame is dropped.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200332TEST_P(VideoAdapterTest, AdaptFramerateTimestampJitter) {
sprangc5d62e22017-04-02 23:53:04 -0700333 const int64_t capture_interval = VideoFormat::FpsToInterval(kDefaultFps);
Åsa Persson2e4419e2018-09-06 15:02:55 +0200334 OnOutputFormatRequest(640, 480, kDefaultFps);
magjed604abe02016-05-19 06:05:40 -0700335
336 adapter_.AdaptFrameResolution(640, 480, capture_interval * 0 / 10,
Jonas Olssona4d87372019-07-05 19:08:33 +0200337 &cropped_width_, &cropped_height_, &out_width_,
338 &out_height_);
magjed604abe02016-05-19 06:05:40 -0700339 EXPECT_GT(out_width_, 0);
340 EXPECT_GT(out_height_, 0);
341
342 adapter_.AdaptFrameResolution(640, 480, capture_interval * 10 / 10 - 1,
Jonas Olssona4d87372019-07-05 19:08:33 +0200343 &cropped_width_, &cropped_height_, &out_width_,
344 &out_height_);
magjed604abe02016-05-19 06:05:40 -0700345 EXPECT_GT(out_width_, 0);
346 EXPECT_GT(out_height_, 0);
347
348 adapter_.AdaptFrameResolution(640, 480, capture_interval * 25 / 10,
Jonas Olssona4d87372019-07-05 19:08:33 +0200349 &cropped_width_, &cropped_height_, &out_width_,
350 &out_height_);
magjed604abe02016-05-19 06:05:40 -0700351 EXPECT_GT(out_width_, 0);
352 EXPECT_GT(out_height_, 0);
353
354 adapter_.AdaptFrameResolution(640, 480, capture_interval * 30 / 10,
Jonas Olssona4d87372019-07-05 19:08:33 +0200355 &cropped_width_, &cropped_height_, &out_width_,
356 &out_height_);
magjed604abe02016-05-19 06:05:40 -0700357 EXPECT_GT(out_width_, 0);
358 EXPECT_GT(out_height_, 0);
359
360 adapter_.AdaptFrameResolution(640, 480, capture_interval * 35 / 10,
Jonas Olssona4d87372019-07-05 19:08:33 +0200361 &cropped_width_, &cropped_height_, &out_width_,
362 &out_height_);
magjed604abe02016-05-19 06:05:40 -0700363 EXPECT_GT(out_width_, 0);
364 EXPECT_GT(out_height_, 0);
365
366 adapter_.AdaptFrameResolution(640, 480, capture_interval * 50 / 10,
Jonas Olssona4d87372019-07-05 19:08:33 +0200367 &cropped_width_, &cropped_height_, &out_width_,
368 &out_height_);
magjed604abe02016-05-19 06:05:40 -0700369 EXPECT_GT(out_width_, 0);
370 EXPECT_GT(out_height_, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000371}
372
373// Adapt the frame rate to be half of the capture rate after capturing no less
374// than 10 frames. Expect no frame dropped before adaptation and frame dropped
375// after adaptation.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200376TEST_P(VideoAdapterTest, AdaptFramerateOntheFly) {
377 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps);
Magnus Jedvert01840572015-04-10 11:18:39 +0200378 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100379 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000380
381 // Verify no frame drop before adaptation.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100382 EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000383
Åsa Persson2e4419e2018-09-06 15:02:55 +0200384 // Adapt the frame rate.
385 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps / 2);
Magnus Jedvert01840572015-04-10 11:18:39 +0200386 for (int i = 0; i < 20; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100387 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000388
389 // Verify frame drop after adaptation.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100390 EXPECT_GT(adapter_wrapper_->GetStats().dropped_frames, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000391}
392
sprangc5d62e22017-04-02 23:53:04 -0700393// Do not adapt the frame rate or the resolution. Expect no frame drop, no
394// cropping, and no resolution change.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200395TEST_P(VideoAdapterTest, AdaptFramerateRequestMax) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200396 adapter_.OnResolutionFramerateRequest(absl::nullopt,
sprangc5d62e22017-04-02 23:53:04 -0700397 std::numeric_limits<int>::max(),
398 std::numeric_limits<int>::max());
399
sprangc5d62e22017-04-02 23:53:04 -0700400 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100401 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
sprangc5d62e22017-04-02 23:53:04 -0700402
403 // Verify no frame drop and no resolution change.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100404 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
sprangc5d62e22017-04-02 23:53:04 -0700405 EXPECT_GE(stats.captured_frames, 10);
406 EXPECT_EQ(0, stats.dropped_frames);
Åsa Persson2e4419e2018-09-06 15:02:55 +0200407 VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
sprangc5d62e22017-04-02 23:53:04 -0700408 EXPECT_TRUE(stats.last_adapt_was_no_op);
409}
410
Åsa Persson2e4419e2018-09-06 15:02:55 +0200411TEST_P(VideoAdapterTest, AdaptFramerateRequestZero) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200412 adapter_.OnResolutionFramerateRequest(absl::nullopt,
sprangc5d62e22017-04-02 23:53:04 -0700413 std::numeric_limits<int>::max(), 0);
sprangc5d62e22017-04-02 23:53:04 -0700414 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100415 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
sprangc5d62e22017-04-02 23:53:04 -0700416
417 // Verify no crash and that frames aren't dropped.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100418 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
sprangc5d62e22017-04-02 23:53:04 -0700419 EXPECT_GE(stats.captured_frames, 10);
420 EXPECT_EQ(10, stats.dropped_frames);
421}
422
423// Adapt the frame rate to be half of the capture rate at the beginning. Expect
424// the number of dropped frames to be half of the number the captured frames.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200425TEST_P(VideoAdapterTest, AdaptFramerateRequestHalf) {
sprangc5d62e22017-04-02 23:53:04 -0700426 adapter_.OnResolutionFramerateRequest(
Danil Chapovalov00c71832018-06-15 15:58:38 +0200427 absl::nullopt, std::numeric_limits<int>::max(), kDefaultFps / 2);
sprangc5d62e22017-04-02 23:53:04 -0700428 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100429 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
sprangc5d62e22017-04-02 23:53:04 -0700430
431 // Verify no crash and that frames aren't dropped.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100432 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
sprangc5d62e22017-04-02 23:53:04 -0700433 EXPECT_GE(stats.captured_frames, 10);
434 EXPECT_EQ(5, stats.dropped_frames);
Åsa Persson2e4419e2018-09-06 15:02:55 +0200435 VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
sprangc5d62e22017-04-02 23:53:04 -0700436}
437
magjed709f73c2016-05-13 10:26:00 -0700438// Set a very high output pixel resolution. Expect no cropping or resolution
439// change.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200440TEST_P(VideoAdapterTest, AdaptFrameResolutionHighLimit) {
441 OnOutputFormatRequest(kWidth * 10, kHeight * 10, kDefaultFps);
442 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0, &cropped_width_,
443 &cropped_height_, &out_width_,
444 &out_height_));
445 EXPECT_EQ(kWidth, cropped_width_);
446 EXPECT_EQ(kHeight, cropped_height_);
447 EXPECT_EQ(kWidth, out_width_);
448 EXPECT_EQ(kHeight, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000449}
450
451// Adapt the frame resolution to be the same as capture resolution. Expect no
magjed709f73c2016-05-13 10:26:00 -0700452// cropping or resolution change.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200453TEST_P(VideoAdapterTest, AdaptFrameResolutionIdentical) {
454 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps);
455 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0, &cropped_width_,
456 &cropped_height_, &out_width_,
457 &out_height_));
458 EXPECT_EQ(kWidth, cropped_width_);
459 EXPECT_EQ(kHeight, cropped_height_);
460 EXPECT_EQ(kWidth, out_width_);
461 EXPECT_EQ(kHeight, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000462}
463
464// Adapt the frame resolution to be a quarter of the capture resolution. Expect
magjed709f73c2016-05-13 10:26:00 -0700465// no cropping, but a resolution change.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200466TEST_P(VideoAdapterTest, AdaptFrameResolutionQuarter) {
467 OnOutputFormatRequest(kWidth / 2, kHeight / 2, kDefaultFps);
468 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0, &cropped_width_,
469 &cropped_height_, &out_width_,
470 &out_height_));
471 EXPECT_EQ(kWidth, cropped_width_);
472 EXPECT_EQ(kHeight, cropped_height_);
473 EXPECT_EQ(kWidth / 2, out_width_);
474 EXPECT_EQ(kHeight / 2, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000475}
476
477// Adapt the pixel resolution to 0. Expect frame drop.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200478TEST_P(VideoAdapterTest, AdaptFrameResolutionDrop) {
479 OnOutputFormatRequest(kWidth * 0, kHeight * 0, kDefaultFps);
480 EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
481 &cropped_width_, &cropped_height_,
482 &out_width_, &out_height_));
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000483}
484
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000485// Adapt the frame resolution to be a quarter of the capture resolution at the
magjed709f73c2016-05-13 10:26:00 -0700486// beginning. Expect no cropping but a resolution change.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200487TEST_P(VideoAdapterTest, AdaptResolution) {
488 OnOutputFormatRequest(kWidth / 2, kHeight / 2, kDefaultFps);
Magnus Jedvert01840572015-04-10 11:18:39 +0200489 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100490 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000491
magjed709f73c2016-05-13 10:26:00 -0700492 // Verify no frame drop, no cropping, and resolution change.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100493 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000494 EXPECT_EQ(0, stats.dropped_frames);
Åsa Persson2e4419e2018-09-06 15:02:55 +0200495 VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth / 2, kHeight / 2);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000496}
497
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000498// Adapt the frame resolution to be a quarter of the capture resolution after
499// capturing no less than 10 frames. Expect no resolution change before
500// adaptation and resolution change after adaptation.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200501TEST_P(VideoAdapterTest, AdaptResolutionOnTheFly) {
502 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps);
Magnus Jedvert01840572015-04-10 11:18:39 +0200503 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100504 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000505
506 // Verify no resolution change before adaptation.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200507 VerifyAdaptedResolution(adapter_wrapper_->GetStats(), kWidth, kHeight, kWidth,
508 kHeight);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000509
510 // Adapt the frame resolution.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200511 OnOutputFormatRequest(kWidth / 2, kHeight / 2, kDefaultFps);
Magnus Jedvert01840572015-04-10 11:18:39 +0200512 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100513 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000514
515 // Verify resolution change after adaptation.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200516 VerifyAdaptedResolution(adapter_wrapper_->GetStats(), kWidth, kHeight,
517 kWidth / 2, kHeight / 2);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000518}
519
Åsa Persson2e4419e2018-09-06 15:02:55 +0200520// Drop all frames for resolution 0x0.
521TEST_P(VideoAdapterTest, DropAllFrames) {
522 OnOutputFormatRequest(kWidth * 0, kHeight * 0, kDefaultFps);
Magnus Jedvert01840572015-04-10 11:18:39 +0200523 for (int i = 0; i < 10; ++i)
Niels Möllera6cc0f92018-02-12 17:14:55 +0100524 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000525
526 // Verify all frames are dropped.
Niels Möllera6cc0f92018-02-12 17:14:55 +0100527 VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000528 EXPECT_GE(stats.captured_frames, 10);
529 EXPECT_EQ(stats.captured_frames, stats.dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000530}
531
Åsa Persson2e4419e2018-09-06 15:02:55 +0200532TEST_P(VideoAdapterTest, TestOnOutputFormatRequest) {
Jonas Olssona4d87372019-07-05 19:08:33 +0200533 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
534 &cropped_height_, &out_width_,
535 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700536 EXPECT_EQ(640, cropped_width_);
537 EXPECT_EQ(400, cropped_height_);
538 EXPECT_EQ(640, out_width_);
539 EXPECT_EQ(400, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000540
Per766ad3b2016-04-05 15:23:49 +0200541 // Format request 640x400.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200542 OnOutputFormatRequest(640, 400, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200543 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
544 &cropped_height_, &out_width_,
545 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700546 EXPECT_EQ(640, cropped_width_);
547 EXPECT_EQ(400, cropped_height_);
548 EXPECT_EQ(640, out_width_);
549 EXPECT_EQ(400, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000550
magjed709f73c2016-05-13 10:26:00 -0700551 // Request 1280x720, higher than input, but aspect 16:9. Expect cropping but
552 // no scaling.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200553 OnOutputFormatRequest(1280, 720, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200554 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
555 &cropped_height_, &out_width_,
556 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700557 EXPECT_EQ(640, cropped_width_);
558 EXPECT_EQ(360, cropped_height_);
559 EXPECT_EQ(640, out_width_);
560 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000561
Per766ad3b2016-04-05 15:23:49 +0200562 // Request 0x0.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200563 OnOutputFormatRequest(0, 0, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200564 EXPECT_FALSE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
565 &cropped_height_, &out_width_,
566 &out_height_));
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000567
magjed709f73c2016-05-13 10:26:00 -0700568 // Request 320x200. Expect scaling, but no cropping.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200569 OnOutputFormatRequest(320, 200, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200570 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
571 &cropped_height_, &out_width_,
572 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700573 EXPECT_EQ(640, cropped_width_);
574 EXPECT_EQ(400, cropped_height_);
575 EXPECT_EQ(320, out_width_);
576 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000577
magjed709f73c2016-05-13 10:26:00 -0700578 // Request resolution close to 2/3 scale. Expect adapt down. Scaling to 2/3
579 // is not optimized and not allowed, therefore 1/2 scaling will be used
580 // instead.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200581 OnOutputFormatRequest(424, 265, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200582 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
583 &cropped_height_, &out_width_,
584 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700585 EXPECT_EQ(640, cropped_width_);
586 EXPECT_EQ(400, cropped_height_);
587 EXPECT_EQ(320, out_width_);
588 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000589
Per766ad3b2016-04-05 15:23:49 +0200590 // Request resolution of 3 / 8. Expect adapt down.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200591 OnOutputFormatRequest(640 * 3 / 8, 400 * 3 / 8, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200592 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
593 &cropped_height_, &out_width_,
594 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700595 EXPECT_EQ(640, cropped_width_);
596 EXPECT_EQ(400, cropped_height_);
597 EXPECT_EQ(640 * 3 / 8, out_width_);
598 EXPECT_EQ(400 * 3 / 8, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000599
Per766ad3b2016-04-05 15:23:49 +0200600 // Switch back up. Expect adapt.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200601 OnOutputFormatRequest(320, 200, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200602 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
603 &cropped_height_, &out_width_,
604 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700605 EXPECT_EQ(640, cropped_width_);
606 EXPECT_EQ(400, cropped_height_);
607 EXPECT_EQ(320, out_width_);
608 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000609
Per766ad3b2016-04-05 15:23:49 +0200610 // Format request 480x300.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200611 OnOutputFormatRequest(480, 300, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200612 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
613 &cropped_height_, &out_width_,
614 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700615 EXPECT_EQ(640, cropped_width_);
616 EXPECT_EQ(400, cropped_height_);
617 EXPECT_EQ(480, out_width_);
618 EXPECT_EQ(300, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000619}
620
Åsa Persson2e4419e2018-09-06 15:02:55 +0200621TEST_P(VideoAdapterTest, TestViewRequestPlusCameraSwitch) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000622 // Start at HD.
Jonas Olssona4d87372019-07-05 19:08:33 +0200623 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
624 &cropped_height_, &out_width_,
625 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700626 EXPECT_EQ(1280, cropped_width_);
627 EXPECT_EQ(720, cropped_height_);
628 EXPECT_EQ(1280, out_width_);
629 EXPECT_EQ(720, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000630
Per766ad3b2016-04-05 15:23:49 +0200631 // Format request for VGA.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200632 OnOutputFormatRequest(640, 360, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200633 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
634 &cropped_height_, &out_width_,
635 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700636 EXPECT_EQ(1280, cropped_width_);
637 EXPECT_EQ(720, cropped_height_);
638 EXPECT_EQ(640, out_width_);
639 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000640
641 // Now, the camera reopens at VGA.
642 // Both the frame and the output format should be 640x360.
Jonas Olssona4d87372019-07-05 19:08:33 +0200643 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
644 &cropped_height_, &out_width_,
645 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700646 EXPECT_EQ(640, cropped_width_);
647 EXPECT_EQ(360, cropped_height_);
648 EXPECT_EQ(640, out_width_);
649 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000650
651 // And another view request comes in for 640x360, which should have no
652 // real impact.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200653 OnOutputFormatRequest(640, 360, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200654 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
655 &cropped_height_, &out_width_,
656 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700657 EXPECT_EQ(640, cropped_width_);
658 EXPECT_EQ(360, cropped_height_);
659 EXPECT_EQ(640, out_width_);
660 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000661}
662
Åsa Persson2e4419e2018-09-06 15:02:55 +0200663TEST_P(VideoAdapterTest, TestVgaWidth) {
Per766ad3b2016-04-05 15:23:49 +0200664 // Reqeuested Output format is 640x360.
Åsa Persson2e4419e2018-09-06 15:02:55 +0200665 OnOutputFormatRequest(640, 360, absl::nullopt);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000666
Jonas Olssona4d87372019-07-05 19:08:33 +0200667 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
668 &cropped_height_, &out_width_,
669 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700670 // Expect cropping.
671 EXPECT_EQ(640, cropped_width_);
672 EXPECT_EQ(360, cropped_height_);
673 EXPECT_EQ(640, out_width_);
674 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000675
676 // But if frames come in at 640x360, we shouldn't adapt them down.
Jonas Olssona4d87372019-07-05 19:08:33 +0200677 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
678 &cropped_height_, &out_width_,
679 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700680 EXPECT_EQ(640, cropped_width_);
681 EXPECT_EQ(360, cropped_height_);
682 EXPECT_EQ(640, out_width_);
683 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000684
Jonas Olssona4d87372019-07-05 19:08:33 +0200685 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
686 &cropped_height_, &out_width_,
687 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700688 EXPECT_EQ(640, cropped_width_);
689 EXPECT_EQ(360, cropped_height_);
690 EXPECT_EQ(640, out_width_);
691 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200692}
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000693
Åsa Persson2e4419e2018-09-06 15:02:55 +0200694TEST_P(VideoAdapterTest, TestOnResolutionRequestInSmallSteps) {
Jonas Olssona4d87372019-07-05 19:08:33 +0200695 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
696 &cropped_height_, &out_width_,
697 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700698 EXPECT_EQ(1280, cropped_width_);
699 EXPECT_EQ(720, cropped_height_);
700 EXPECT_EQ(1280, out_width_);
701 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200702
703 // Adapt down one step.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200704 adapter_.OnResolutionFramerateRequest(absl::nullopt, 1280 * 720 - 1,
sprangc5d62e22017-04-02 23:53:04 -0700705 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200706 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
707 &cropped_height_, &out_width_,
708 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700709 EXPECT_EQ(1280, cropped_width_);
710 EXPECT_EQ(720, cropped_height_);
711 EXPECT_EQ(960, out_width_);
712 EXPECT_EQ(540, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200713
714 // Adapt down one step more.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200715 adapter_.OnResolutionFramerateRequest(absl::nullopt, 960 * 540 - 1,
sprangc5d62e22017-04-02 23:53:04 -0700716 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200717 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
718 &cropped_height_, &out_width_,
719 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700720 EXPECT_EQ(1280, cropped_width_);
721 EXPECT_EQ(720, cropped_height_);
722 EXPECT_EQ(640, out_width_);
723 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200724
725 // Adapt down one step more.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200726 adapter_.OnResolutionFramerateRequest(absl::nullopt, 640 * 360 - 1,
sprangc5d62e22017-04-02 23:53:04 -0700727 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200728 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
729 &cropped_height_, &out_width_,
730 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700731 EXPECT_EQ(1280, cropped_width_);
732 EXPECT_EQ(720, cropped_height_);
733 EXPECT_EQ(480, out_width_);
734 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200735
736 // Adapt up one step.
Jonas Olssona4d87372019-07-05 19:08:33 +0200737 adapter_.OnResolutionFramerateRequest(640 * 360, 960 * 540,
sprangc5d62e22017-04-02 23:53:04 -0700738 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200739 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
740 &cropped_height_, &out_width_,
741 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700742 EXPECT_EQ(1280, cropped_width_);
743 EXPECT_EQ(720, cropped_height_);
744 EXPECT_EQ(640, out_width_);
745 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200746
747 // Adapt up one step more.
Jonas Olssona4d87372019-07-05 19:08:33 +0200748 adapter_.OnResolutionFramerateRequest(960 * 540, 1280 * 720,
sprangc5d62e22017-04-02 23:53:04 -0700749 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200750 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
751 &cropped_height_, &out_width_,
752 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700753 EXPECT_EQ(1280, cropped_width_);
754 EXPECT_EQ(720, cropped_height_);
755 EXPECT_EQ(960, out_width_);
756 EXPECT_EQ(540, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200757
758 // Adapt up one step more.
Jonas Olssona4d87372019-07-05 19:08:33 +0200759 adapter_.OnResolutionFramerateRequest(1280 * 720, 1920 * 1080,
sprangc5d62e22017-04-02 23:53:04 -0700760 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200761 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
762 &cropped_height_, &out_width_,
763 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700764 EXPECT_EQ(1280, cropped_width_);
765 EXPECT_EQ(720, cropped_height_);
766 EXPECT_EQ(1280, out_width_);
767 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200768}
769
Åsa Persson2e4419e2018-09-06 15:02:55 +0200770TEST_P(VideoAdapterTest, TestOnResolutionRequestMaxZero) {
Jonas Olssona4d87372019-07-05 19:08:33 +0200771 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
772 &cropped_height_, &out_width_,
773 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700774 EXPECT_EQ(1280, cropped_width_);
775 EXPECT_EQ(720, cropped_height_);
776 EXPECT_EQ(1280, out_width_);
777 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200778
Danil Chapovalov00c71832018-06-15 15:58:38 +0200779 adapter_.OnResolutionFramerateRequest(absl::nullopt, 0,
sprangc5d62e22017-04-02 23:53:04 -0700780 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200781 EXPECT_FALSE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
782 &cropped_height_, &out_width_,
783 &out_height_));
Per766ad3b2016-04-05 15:23:49 +0200784}
785
Åsa Persson2e4419e2018-09-06 15:02:55 +0200786TEST_P(VideoAdapterTest, TestOnResolutionRequestInLargeSteps) {
sprang84a37592017-02-10 07:04:27 -0800787 // Large step down.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200788 adapter_.OnResolutionFramerateRequest(absl::nullopt, 640 * 360 - 1,
sprangc5d62e22017-04-02 23:53:04 -0700789 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200790 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
791 &cropped_height_, &out_width_,
792 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700793 EXPECT_EQ(1280, cropped_width_);
794 EXPECT_EQ(720, cropped_height_);
795 EXPECT_EQ(480, out_width_);
796 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200797
sprang84a37592017-02-10 07:04:27 -0800798 // Large step up.
Oskar Sundbom78807582017-11-16 11:09:55 +0100799 adapter_.OnResolutionFramerateRequest(1280 * 720, 1920 * 1080,
sprangc5d62e22017-04-02 23:53:04 -0700800 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200801 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
802 &cropped_height_, &out_width_,
803 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700804 EXPECT_EQ(1280, cropped_width_);
805 EXPECT_EQ(720, cropped_height_);
806 EXPECT_EQ(1280, out_width_);
807 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200808}
809
Åsa Persson2e4419e2018-09-06 15:02:55 +0200810TEST_P(VideoAdapterTest, TestOnOutputFormatRequestCapsMaxResolution) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200811 adapter_.OnResolutionFramerateRequest(absl::nullopt, 640 * 360 - 1,
sprangc5d62e22017-04-02 23:53:04 -0700812 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200813 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
814 &cropped_height_, &out_width_,
815 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700816 EXPECT_EQ(1280, cropped_width_);
817 EXPECT_EQ(720, cropped_height_);
818 EXPECT_EQ(480, out_width_);
819 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200820
Åsa Persson2e4419e2018-09-06 15:02:55 +0200821 OnOutputFormatRequest(640, 360, absl::nullopt);
Jonas Olssona4d87372019-07-05 19:08:33 +0200822 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
823 &cropped_height_, &out_width_,
824 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700825 EXPECT_EQ(1280, cropped_width_);
826 EXPECT_EQ(720, cropped_height_);
827 EXPECT_EQ(480, out_width_);
828 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200829
Danil Chapovalov00c71832018-06-15 15:58:38 +0200830 adapter_.OnResolutionFramerateRequest(absl::nullopt, 960 * 720,
sprangc5d62e22017-04-02 23:53:04 -0700831 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200832 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
833 &cropped_height_, &out_width_,
834 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700835 EXPECT_EQ(1280, cropped_width_);
836 EXPECT_EQ(720, cropped_height_);
837 EXPECT_EQ(640, out_width_);
838 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000839}
840
Åsa Persson2e4419e2018-09-06 15:02:55 +0200841TEST_P(VideoAdapterTest, TestOnResolutionRequestReset) {
Jonas Olssona4d87372019-07-05 19:08:33 +0200842 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
843 &cropped_height_, &out_width_,
844 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700845 EXPECT_EQ(1280, cropped_width_);
846 EXPECT_EQ(720, cropped_height_);
847 EXPECT_EQ(1280, out_width_);
848 EXPECT_EQ(720, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000849
Danil Chapovalov00c71832018-06-15 15:58:38 +0200850 adapter_.OnResolutionFramerateRequest(absl::nullopt, 640 * 360 - 1,
sprangc5d62e22017-04-02 23:53:04 -0700851 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200852 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
853 &cropped_height_, &out_width_,
854 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700855 EXPECT_EQ(1280, cropped_width_);
856 EXPECT_EQ(720, cropped_height_);
857 EXPECT_EQ(480, out_width_);
858 EXPECT_EQ(270, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000859
Danil Chapovalov00c71832018-06-15 15:58:38 +0200860 adapter_.OnResolutionFramerateRequest(absl::nullopt,
sprangc5d62e22017-04-02 23:53:04 -0700861 std::numeric_limits<int>::max(),
862 std::numeric_limits<int>::max());
Jonas Olssona4d87372019-07-05 19:08:33 +0200863 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
864 &cropped_height_, &out_width_,
865 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700866 EXPECT_EQ(1280, cropped_width_);
867 EXPECT_EQ(720, cropped_height_);
868 EXPECT_EQ(1280, out_width_);
869 EXPECT_EQ(720, out_height_);
870}
871
Åsa Persson2e4419e2018-09-06 15:02:55 +0200872TEST_P(VideoAdapterTest, TestOnOutputFormatRequestResolutionReset) {
873 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
874 &cropped_height_, &out_width_,
875 &out_height_));
876 EXPECT_EQ(1280, cropped_width_);
877 EXPECT_EQ(720, cropped_height_);
878 EXPECT_EQ(1280, out_width_);
879 EXPECT_EQ(720, out_height_);
880
881 adapter_.OnOutputFormatRequest(absl::nullopt, 640 * 360 - 1, absl::nullopt);
882 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
883 &cropped_height_, &out_width_,
884 &out_height_));
885 EXPECT_EQ(1280, cropped_width_);
886 EXPECT_EQ(720, cropped_height_);
887 EXPECT_EQ(480, out_width_);
888 EXPECT_EQ(270, out_height_);
889
890 adapter_.OnOutputFormatRequest(absl::nullopt, absl::nullopt, absl::nullopt);
891 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
892 &cropped_height_, &out_width_,
893 &out_height_));
894 EXPECT_EQ(1280, cropped_width_);
895 EXPECT_EQ(720, cropped_height_);
896 EXPECT_EQ(1280, out_width_);
897 EXPECT_EQ(720, out_height_);
898}
899
900TEST_P(VideoAdapterTest, TestOnOutputFormatRequestFpsReset) {
901 OnOutputFormatRequest(kWidth, kHeight, kDefaultFps / 2);
902 for (int i = 0; i < 10; ++i)
903 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
904
905 // Verify frame drop.
906 const int dropped_frames = adapter_wrapper_->GetStats().dropped_frames;
907 EXPECT_GT(dropped_frames, 0);
908
909 // Reset frame rate.
910 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);
911 for (int i = 0; i < 20; ++i)
912 adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
913
914 // Verify no frame drop after reset.
915 EXPECT_EQ(dropped_frames, adapter_wrapper_->GetStats().dropped_frames);
916}
917
918TEST_P(VideoAdapterTest, RequestAspectRatio) {
919 // Request aspect ratio 320/180 (16:9), smaller than input, but no resolution
920 // limit. Expect cropping but no scaling.
921 adapter_.OnOutputFormatRequest(std::make_pair(320, 180), absl::nullopt,
922 absl::nullopt);
923 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
924 &cropped_height_, &out_width_,
925 &out_height_));
926 EXPECT_EQ(640, cropped_width_);
927 EXPECT_EQ(360, cropped_height_);
928 EXPECT_EQ(640, out_width_);
929 EXPECT_EQ(360, out_height_);
930}
931
932TEST_P(VideoAdapterTest, RequestAspectRatioWithDifferentOrientation) {
933 // Request 720x1280, higher than input, but aspect 16:9. Orientation should
934 // not matter, expect cropping but no scaling.
935 OnOutputFormatRequest(720, 1280, absl::nullopt);
936 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
937 &cropped_height_, &out_width_,
938 &out_height_));
939 EXPECT_EQ(640, cropped_width_);
940 EXPECT_EQ(360, cropped_height_);
941 EXPECT_EQ(640, out_width_);
942 EXPECT_EQ(360, out_height_);
943}
944
945TEST_P(VideoAdapterTest, InvalidAspectRatioIgnored) {
946 // Request aspect ratio 320/0. Expect no cropping.
947 adapter_.OnOutputFormatRequest(std::make_pair(320, 0), absl::nullopt,
948 absl::nullopt);
949 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
950 &cropped_height_, &out_width_,
951 &out_height_));
952 EXPECT_EQ(640, cropped_width_);
953 EXPECT_EQ(400, cropped_height_);
954 EXPECT_EQ(640, out_width_);
955 EXPECT_EQ(400, out_height_);
956}
957
958TEST_P(VideoAdapterTest, TestCroppingWithResolutionRequest) {
magjed709f73c2016-05-13 10:26:00 -0700959 // Ask for 640x360 (16:9 aspect).
Åsa Persson2e4419e2018-09-06 15:02:55 +0200960 OnOutputFormatRequest(640, 360, absl::nullopt);
magjed709f73c2016-05-13 10:26:00 -0700961 // Send 640x480 (4:3 aspect).
Jonas Olssona4d87372019-07-05 19:08:33 +0200962 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
963 &cropped_height_, &out_width_,
964 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700965 // Expect cropping to 16:9 format and no scaling.
966 EXPECT_EQ(640, cropped_width_);
967 EXPECT_EQ(360, cropped_height_);
968 EXPECT_EQ(640, out_width_);
969 EXPECT_EQ(360, out_height_);
970
971 // Adapt down one step.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200972 adapter_.OnResolutionFramerateRequest(absl::nullopt, 640 * 360 - 1,
sprangc5d62e22017-04-02 23:53:04 -0700973 std::numeric_limits<int>::max());
magjed709f73c2016-05-13 10:26:00 -0700974 // Expect cropping to 16:9 format and 3/4 scaling.
Jonas Olssona4d87372019-07-05 19:08:33 +0200975 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
976 &cropped_height_, &out_width_,
977 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700978 EXPECT_EQ(640, cropped_width_);
979 EXPECT_EQ(360, cropped_height_);
980 EXPECT_EQ(480, out_width_);
981 EXPECT_EQ(270, out_height_);
982
983 // Adapt down one step more.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200984 adapter_.OnResolutionFramerateRequest(absl::nullopt, 480 * 270 - 1,
sprangc5d62e22017-04-02 23:53:04 -0700985 std::numeric_limits<int>::max());
magjed709f73c2016-05-13 10:26:00 -0700986 // Expect cropping to 16:9 format and 1/2 scaling.
Jonas Olssona4d87372019-07-05 19:08:33 +0200987 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
988 &cropped_height_, &out_width_,
989 &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700990 EXPECT_EQ(640, cropped_width_);
991 EXPECT_EQ(360, cropped_height_);
992 EXPECT_EQ(320, out_width_);
993 EXPECT_EQ(180, out_height_);
994
995 // Adapt up one step.
Oskar Sundbom78807582017-11-16 11:09:55 +0100996 adapter_.OnResolutionFramerateRequest(480 * 270, 640 * 360,
sprangc5d62e22017-04-02 23:53:04 -0700997 std::numeric_limits<int>::max());
magjed709f73c2016-05-13 10:26:00 -0700998 // Expect cropping to 16:9 format and 3/4 scaling.
Jonas Olssona4d87372019-07-05 19:08:33 +0200999 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
1000 &cropped_height_, &out_width_,
1001 &out_height_));
magjed709f73c2016-05-13 10:26:00 -07001002 EXPECT_EQ(640, cropped_width_);
1003 EXPECT_EQ(360, cropped_height_);
1004 EXPECT_EQ(480, out_width_);
1005 EXPECT_EQ(270, out_height_);
1006
1007 // Adapt up one step more.
Oskar Sundbom78807582017-11-16 11:09:55 +01001008 adapter_.OnResolutionFramerateRequest(640 * 360, 960 * 540,
sprangc5d62e22017-04-02 23:53:04 -07001009 std::numeric_limits<int>::max());
magjed709f73c2016-05-13 10:26:00 -07001010 // Expect cropping to 16:9 format and no scaling.
Jonas Olssona4d87372019-07-05 19:08:33 +02001011 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
1012 &cropped_height_, &out_width_,
1013 &out_height_));
magjed709f73c2016-05-13 10:26:00 -07001014 EXPECT_EQ(640, cropped_width_);
1015 EXPECT_EQ(360, cropped_height_);
1016 EXPECT_EQ(640, out_width_);
1017 EXPECT_EQ(360, out_height_);
1018
1019 // Try to adapt up one step more.
Oskar Sundbom78807582017-11-16 11:09:55 +01001020 adapter_.OnResolutionFramerateRequest(960 * 540, 1280 * 720,
sprangc5d62e22017-04-02 23:53:04 -07001021 std::numeric_limits<int>::max());
magjed709f73c2016-05-13 10:26:00 -07001022 // Expect cropping to 16:9 format and no scaling.
Jonas Olssona4d87372019-07-05 19:08:33 +02001023 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
1024 &cropped_height_, &out_width_,
1025 &out_height_));
magjed709f73c2016-05-13 10:26:00 -07001026 EXPECT_EQ(640, cropped_width_);
1027 EXPECT_EQ(360, cropped_height_);
1028 EXPECT_EQ(640, out_width_);
1029 EXPECT_EQ(360, out_height_);
1030}
1031
Åsa Persson2e4419e2018-09-06 15:02:55 +02001032TEST_P(VideoAdapterTest, TestCroppingOddResolution) {
magjed709f73c2016-05-13 10:26:00 -07001033 // Ask for 640x360 (16:9 aspect), with 3/16 scaling.
Åsa Persson2e4419e2018-09-06 15:02:55 +02001034 OnOutputFormatRequest(640, 360, absl::nullopt);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001035 adapter_.OnResolutionFramerateRequest(absl::nullopt,
sprangc5d62e22017-04-02 23:53:04 -07001036 640 * 360 * 3 / 16 * 3 / 16,
1037 std::numeric_limits<int>::max());
magjed709f73c2016-05-13 10:26:00 -07001038
1039 // Send 640x480 (4:3 aspect).
Jonas Olssona4d87372019-07-05 19:08:33 +02001040 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
1041 &cropped_height_, &out_width_,
1042 &out_height_));
magjed709f73c2016-05-13 10:26:00 -07001043
1044 // Instead of getting the exact aspect ratio with cropped resolution 640x360,
1045 // the resolution should be adjusted to get a perfect scale factor instead.
1046 EXPECT_EQ(640, cropped_width_);
1047 EXPECT_EQ(368, cropped_height_);
1048 EXPECT_EQ(120, out_width_);
1049 EXPECT_EQ(69, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +00001050}
1051
Åsa Persson2e4419e2018-09-06 15:02:55 +02001052TEST_P(VideoAdapterTest, TestAdaptToVerySmallResolution) {
kthelgasonc8474172016-12-08 08:04:51 -08001053 // Ask for 1920x1080 (16:9 aspect), with 1/16 scaling.
1054 const int w = 1920;
1055 const int h = 1080;
Åsa Persson2e4419e2018-09-06 15:02:55 +02001056 OnOutputFormatRequest(w, h, absl::nullopt);
Danil Chapovalov00c71832018-06-15 15:58:38 +02001057 adapter_.OnResolutionFramerateRequest(absl::nullopt, w * h * 1 / 16 * 1 / 16,
sprangc5d62e22017-04-02 23:53:04 -07001058 std::numeric_limits<int>::max());
kthelgasonc8474172016-12-08 08:04:51 -08001059
1060 // Send 1920x1080 (16:9 aspect).
1061 EXPECT_TRUE(adapter_.AdaptFrameResolution(
1062 w, h, 0, &cropped_width_, &cropped_height_, &out_width_, &out_height_));
1063
1064 // Instead of getting the exact aspect ratio with cropped resolution 1920x1080
1065 // the resolution should be adjusted to get a perfect scale factor instead.
1066 EXPECT_EQ(1920, cropped_width_);
1067 EXPECT_EQ(1072, cropped_height_);
1068 EXPECT_EQ(120, out_width_);
1069 EXPECT_EQ(67, out_height_);
1070
1071 // Adapt back up one step to 3/32.
Oskar Sundbom78807582017-11-16 11:09:55 +01001072 adapter_.OnResolutionFramerateRequest(w * h * 3 / 32 * 3 / 32,
1073 w * h * 1 / 8 * 1 / 8,
1074 std::numeric_limits<int>::max());
kthelgasonc8474172016-12-08 08:04:51 -08001075
1076 // Send 1920x1080 (16:9 aspect).
1077 EXPECT_TRUE(adapter_.AdaptFrameResolution(
1078 w, h, 0, &cropped_width_, &cropped_height_, &out_width_, &out_height_));
1079
1080 EXPECT_EQ(180, out_width_);
1081 EXPECT_EQ(99, out_height_);
1082}
1083
Åsa Persson2e4419e2018-09-06 15:02:55 +02001084TEST_P(VideoAdapterTest, AdaptFrameResolutionDropWithResolutionRequest) {
1085 OnOutputFormatRequest(0, 0, kDefaultFps);
1086 EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1087 &cropped_width_, &cropped_height_,
1088 &out_width_, &out_height_));
kthelgasonc8474172016-12-08 08:04:51 -08001089
Oskar Sundbom78807582017-11-16 11:09:55 +01001090 adapter_.OnResolutionFramerateRequest(960 * 540,
sprangc5d62e22017-04-02 23:53:04 -07001091 std::numeric_limits<int>::max(),
1092 std::numeric_limits<int>::max());
kthelgasonc8474172016-12-08 08:04:51 -08001093
1094 // Still expect all frames to be dropped
Åsa Persson2e4419e2018-09-06 15:02:55 +02001095 EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1096 &cropped_width_, &cropped_height_,
1097 &out_width_, &out_height_));
kthelgasonc8474172016-12-08 08:04:51 -08001098
Danil Chapovalov00c71832018-06-15 15:58:38 +02001099 adapter_.OnResolutionFramerateRequest(absl::nullopt, 640 * 480 - 1,
sprangc5d62e22017-04-02 23:53:04 -07001100 std::numeric_limits<int>::max());
kthelgasonc8474172016-12-08 08:04:51 -08001101
1102 // Still expect all frames to be dropped
Åsa Persson2e4419e2018-09-06 15:02:55 +02001103 EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1104 &cropped_width_, &cropped_height_,
1105 &out_width_, &out_height_));
kthelgasonc8474172016-12-08 08:04:51 -08001106}
1107
Magnus Jedvert6d230d72017-02-22 18:30:27 +01001108// Test that we will adapt to max given a target pixel count close to max.
Åsa Persson2e4419e2018-09-06 15:02:55 +02001109TEST_P(VideoAdapterTest, TestAdaptToMax) {
1110 OnOutputFormatRequest(640, 360, kDefaultFps);
Oskar Sundbom78807582017-11-16 11:09:55 +01001111 adapter_.OnResolutionFramerateRequest(640 * 360 - 1 /* target */,
1112 std::numeric_limits<int>::max(),
1113 std::numeric_limits<int>::max());
Magnus Jedvert6d230d72017-02-22 18:30:27 +01001114
1115 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
1116 &cropped_height_, &out_width_,
1117 &out_height_));
1118 EXPECT_EQ(640, out_width_);
1119 EXPECT_EQ(360, out_height_);
1120}
Magnus Jedvert06aa2092018-10-26 14:00:18 +02001121
1122// Test adjusting to 16:9 in landscape, and 9:16 in portrait.
1123TEST(VideoAdapterTestMultipleOrientation, TestNormal) {
1124 VideoAdapter video_adapter;
1125 video_adapter.OnOutputFormatRequest(std::make_pair(640, 360), 640 * 360,
1126 std::make_pair(360, 640), 360 * 640, 30);
1127
1128 int cropped_width;
1129 int cropped_height;
1130 int out_width;
1131 int out_height;
1132 EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1133 /* in_width= */ 640, /* in_height= */ 480, /* in_timestamp_ns= */ 0,
1134 &cropped_width, &cropped_height, &out_width, &out_height));
1135 EXPECT_EQ(640, cropped_width);
1136 EXPECT_EQ(360, cropped_height);
1137 EXPECT_EQ(640, out_width);
1138 EXPECT_EQ(360, out_height);
1139
1140 EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1141 /* in_width= */ 480, /* in_height= */ 640,
1142 /* in_timestamp_ns= */ rtc::kNumNanosecsPerSec / 30, &cropped_width,
1143 &cropped_height, &out_width, &out_height));
1144 EXPECT_EQ(360, cropped_width);
1145 EXPECT_EQ(640, cropped_height);
1146 EXPECT_EQ(360, out_width);
1147 EXPECT_EQ(640, out_height);
1148}
1149
1150// Force output to be 9:16, even for landscape input.
1151TEST(VideoAdapterTestMultipleOrientation, TestForcePortrait) {
1152 VideoAdapter video_adapter;
1153 video_adapter.OnOutputFormatRequest(std::make_pair(360, 640), 640 * 360,
1154 std::make_pair(360, 640), 360 * 640, 30);
1155
1156 int cropped_width;
1157 int cropped_height;
1158 int out_width;
1159 int out_height;
1160 EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1161 /* in_width= */ 640, /* in_height= */ 480, /* in_timestamp_ns= */ 0,
1162 &cropped_width, &cropped_height, &out_width, &out_height));
1163 EXPECT_EQ(270, cropped_width);
1164 EXPECT_EQ(480, cropped_height);
1165 EXPECT_EQ(270, out_width);
1166 EXPECT_EQ(480, out_height);
1167
1168 EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1169 /* in_width= */ 480, /* in_height= */ 640,
1170 /* in_timestamp_ns= */ rtc::kNumNanosecsPerSec / 30, &cropped_width,
1171 &cropped_height, &out_width, &out_height));
1172 EXPECT_EQ(360, cropped_width);
1173 EXPECT_EQ(640, cropped_height);
1174 EXPECT_EQ(360, out_width);
1175 EXPECT_EQ(640, out_height);
1176}
1177
Åsa Persson3f7e0ed2019-10-18 15:03:13 +02001178TEST_P(VideoAdapterTest, AdaptResolutionInSteps) {
1179 const int kWidth = 1280;
1180 const int kHeight = 720;
1181 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt); // 16:9 aspect.
1182
1183 // Scale factors: 3/4, 2/3, 3/4, 2/3, ...
1184 // Scale : 3/4, 1/2, 3/8, 1/4, 3/16, 1/8.
1185 const int kExpectedWidths[] = {960, 640, 480, 320, 240, 160};
1186 const int kExpectedHeights[] = {540, 360, 270, 180, 135, 90};
1187
1188 int request_width = kWidth;
1189 int request_height = kHeight;
1190
1191 for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1192 // Adapt down one step.
1193 adapter_.OnResolutionFramerateRequest(absl::nullopt,
1194 request_width * request_height - 1,
1195 std::numeric_limits<int>::max());
1196 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1197 &cropped_width_, &cropped_height_,
1198 &out_width_, &out_height_));
1199 EXPECT_EQ(kExpectedWidths[i], out_width_);
1200 EXPECT_EQ(kExpectedHeights[i], out_height_);
1201 request_width = out_width_;
1202 request_height = out_height_;
1203 }
1204}
1205
1206// Scale factors are 3/4, 2/3, 3/4, 2/3, ... (see test above).
1207// In VideoAdapterTestVariableStartScale, first scale factor depends on
1208// resolution. May start with:
1209// - 2/3 (if width/height multiple of 3) or
1210// - 2/3, 2/3 (if width/height multiple of 9).
1211TEST_P(VideoAdapterTestVariableStartScale, AdaptResolutionInStepsFirst3_4) {
1212 const int kWidth = 1280;
1213 const int kHeight = 720;
1214 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt); // 16:9 aspect.
1215
1216 // Scale factors: 3/4, 2/3, 3/4, 2/3, ...
1217 // Scale : 3/4, 1/2, 3/8, 1/4, 3/16, 1/8.
1218 const int kExpectedWidths[] = {960, 640, 480, 320, 240, 160};
1219 const int kExpectedHeights[] = {540, 360, 270, 180, 135, 90};
1220
1221 int request_width = kWidth;
1222 int request_height = kHeight;
1223
1224 for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1225 // Adapt down one step.
1226 adapter_.OnResolutionFramerateRequest(absl::nullopt,
1227 request_width * request_height - 1,
1228 std::numeric_limits<int>::max());
1229 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1230 &cropped_width_, &cropped_height_,
1231 &out_width_, &out_height_));
1232 EXPECT_EQ(kExpectedWidths[i], out_width_);
1233 EXPECT_EQ(kExpectedHeights[i], out_height_);
1234 request_width = out_width_;
1235 request_height = out_height_;
1236 }
1237}
1238
1239TEST_P(VideoAdapterTestVariableStartScale, AdaptResolutionInStepsFirst2_3) {
1240 const int kWidth = 1920;
1241 const int kHeight = 1080;
1242 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt); // 16:9 aspect.
1243
1244 // Scale factors: 2/3, 3/4, 2/3, 3/4, ...
1245 // Scale: 2/3, 1/2, 1/3, 1/4, 1/6, 1/8, 1/12.
1246 const int kExpectedWidths[] = {1280, 960, 640, 480, 320, 240, 160};
1247 const int kExpectedHeights[] = {720, 540, 360, 270, 180, 135, 90};
1248
1249 int request_width = kWidth;
1250 int request_height = kHeight;
1251
1252 for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1253 // Adapt down one step.
1254 adapter_.OnResolutionFramerateRequest(absl::nullopt,
1255 request_width * request_height - 1,
1256 std::numeric_limits<int>::max());
1257 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1258 &cropped_width_, &cropped_height_,
1259 &out_width_, &out_height_));
1260 EXPECT_EQ(kExpectedWidths[i], out_width_);
1261 EXPECT_EQ(kExpectedHeights[i], out_height_);
1262 request_width = out_width_;
1263 request_height = out_height_;
1264 }
1265}
1266
1267TEST_P(VideoAdapterTestVariableStartScale, AdaptResolutionInStepsFirst2x2_3) {
1268 const int kWidth = 1440;
1269 const int kHeight = 1080;
1270 OnOutputFormatRequest(kWidth, kHeight, absl::nullopt); // 4:3 aspect.
1271
1272 // Scale factors: 2/3, 2/3, 3/4, 2/3, 3/4, ...
1273 // Scale : 2/3, 4/9, 1/3, 2/9, 1/6, 1/9, 1/12, 1/18, 1/24, 1/36.
1274 const int kExpectedWidths[] = {960, 640, 480, 320, 240, 160, 120, 80, 60, 40};
1275 const int kExpectedHeights[] = {720, 480, 360, 240, 180, 120, 90, 60, 45, 30};
1276
1277 int request_width = kWidth;
1278 int request_height = kHeight;
1279
1280 for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1281 // Adapt down one step.
1282 adapter_.OnResolutionFramerateRequest(absl::nullopt,
1283 request_width * request_height - 1,
1284 std::numeric_limits<int>::max());
1285 EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1286 &cropped_width_, &cropped_height_,
1287 &out_width_, &out_height_));
1288 EXPECT_EQ(kExpectedWidths[i], out_width_);
1289 EXPECT_EQ(kExpectedHeights[i], out_height_);
1290 request_width = out_width_;
1291 request_height = out_height_;
1292 }
1293}
1294
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +00001295} // namespace cricket