blob: 7f660ef37f2f3086ff438b782e04ff4e9dcceec5 [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
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000011#include <limits.h> // For INT_MAX
kwiberg686a8ef2016-02-26 03:00:35 -080012
kwibergbfefb032016-05-01 14:53:46 -070013#include <memory>
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000014#include <string>
15#include <vector>
16
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000017#include "webrtc/base/gunit.h"
18#include "webrtc/base/logging.h"
kjellandera96e2d72016-02-04 23:52:28 -080019#include "webrtc/media/base/fakevideocapturer.h"
20#include "webrtc/media/base/mediachannel.h"
21#include "webrtc/media/base/testutils.h"
22#include "webrtc/media/base/videoadapter.h"
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000023
24namespace cricket {
25
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000026class VideoAdapterTest : public testing::Test {
27 public:
28 virtual void SetUp() {
Magnus Jedvert01840572015-04-10 11:18:39 +020029 capturer_.reset(new FakeVideoCapturer);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000030 capture_format_ = capturer_->GetSupportedFormats()->at(0);
magjed604abe02016-05-19 06:05:40 -070031 capture_format_.interval = VideoFormat::FpsToInterval(30);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000032
Per766ad3b2016-04-05 15:23:49 +020033 listener_.reset(new VideoCapturerListener(&adapter_));
nissef5297a02016-09-30 01:34:27 -070034 capturer_->AddOrUpdateSink(listener_.get(), rtc::VideoSinkWants());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000035 }
36
pbos@webrtc.org75c3ec12014-08-27 18:16:13 +000037 virtual void TearDown() {
38 // Explicitly disconnect the VideoCapturer before to avoid data races
39 // (frames delivered to VideoCapturerListener while it's being destructed).
nissef5297a02016-09-30 01:34:27 -070040 capturer_->RemoveSink(listener_.get());
pbos@webrtc.org75c3ec12014-08-27 18:16:13 +000041 }
42
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000043 protected:
nissef5297a02016-09-30 01:34:27 -070044 class VideoCapturerListener
nisseacd935b2016-11-11 03:55:13 -080045 : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000046 public:
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000047 struct Stats {
48 int captured_frames;
49 int dropped_frames;
50 bool last_adapt_was_no_op;
51
magjed709f73c2016-05-13 10:26:00 -070052 int cropped_width;
53 int cropped_height;
54 int out_width;
55 int out_height;
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000056 };
57
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000058 explicit VideoCapturerListener(VideoAdapter* adapter)
59 : video_adapter_(adapter),
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000060 captured_frames_(0),
61 dropped_frames_(0),
62 last_adapt_was_no_op_(false) {
63 }
64
nisseacd935b2016-11-11 03:55:13 -080065 void OnFrame(const webrtc::VideoFrame& frame) {
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000066 rtc::CritScope lock(&crit_);
nissef5297a02016-09-30 01:34:27 -070067 const int in_width = frame.width();
68 const int in_height = frame.height();
magjed709f73c2016-05-13 10:26:00 -070069 int cropped_width;
70 int cropped_height;
71 int out_width;
72 int out_height;
nissef5297a02016-09-30 01:34:27 -070073 if (video_adapter_->AdaptFrameResolution(
74 in_width, in_height,
75 frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec,
76 &cropped_width, &cropped_height, &out_width, &out_height)) {
magjed709f73c2016-05-13 10:26:00 -070077 cropped_width_ = cropped_width;
78 cropped_height_ = cropped_height;
79 out_width_ = out_width;
80 out_height_ = out_height;
81 last_adapt_was_no_op_ =
82 (in_width == cropped_width && in_height == cropped_height &&
83 in_width == out_width && in_height == out_height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000084 } else {
85 ++dropped_frames_;
86 }
87 ++captured_frames_;
88 }
89
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000090 Stats GetStats() {
91 rtc::CritScope lock(&crit_);
92 Stats stats;
93 stats.captured_frames = captured_frames_;
94 stats.dropped_frames = dropped_frames_;
95 stats.last_adapt_was_no_op = last_adapt_was_no_op_;
magjed709f73c2016-05-13 10:26:00 -070096 stats.cropped_width = cropped_width_;
97 stats.cropped_height = cropped_height_;
98 stats.out_width = out_width_;
99 stats.out_height = out_height_;
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000100 return stats;
101 }
102
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000103 private:
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000104 rtc::CriticalSection crit_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000105 VideoAdapter* video_adapter_;
magjed709f73c2016-05-13 10:26:00 -0700106 int cropped_width_;
107 int cropped_height_;
108 int out_width_;
109 int out_height_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000110 int captured_frames_;
111 int dropped_frames_;
112 bool last_adapt_was_no_op_;
113 };
114
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000115
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000116 void VerifyAdaptedResolution(const VideoCapturerListener::Stats& stats,
magjed709f73c2016-05-13 10:26:00 -0700117 int cropped_width,
118 int cropped_height,
119 int out_width,
120 int out_height) {
121 EXPECT_EQ(cropped_width, stats.cropped_width);
122 EXPECT_EQ(cropped_height, stats.cropped_height);
123 EXPECT_EQ(out_width, stats.out_width);
124 EXPECT_EQ(out_height, stats.out_height);
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000125 }
126
kwiberg686a8ef2016-02-26 03:00:35 -0800127 std::unique_ptr<FakeVideoCapturer> capturer_;
Per766ad3b2016-04-05 15:23:49 +0200128 VideoAdapter adapter_;
magjed709f73c2016-05-13 10:26:00 -0700129 int cropped_width_;
130 int cropped_height_;
131 int out_width_;
132 int out_height_;
kwiberg686a8ef2016-02-26 03:00:35 -0800133 std::unique_ptr<VideoCapturerListener> listener_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000134 VideoFormat capture_format_;
135};
136
magjed709f73c2016-05-13 10:26:00 -0700137// Do not adapt the frame rate or the resolution. Expect no frame drop, no
138// cropping, and no resolution change.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000139TEST_F(VideoAdapterTest, AdaptNothing) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000140 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200141 for (int i = 0; i < 10; ++i)
142 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000143
144 // Verify no frame drop and no resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000145 VideoCapturerListener::Stats stats = listener_->GetStats();
146 EXPECT_GE(stats.captured_frames, 10);
147 EXPECT_EQ(0, stats.dropped_frames);
magjed709f73c2016-05-13 10:26:00 -0700148 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height,
149 capture_format_.width, capture_format_.height);
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000150 EXPECT_TRUE(stats.last_adapt_was_no_op);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000151}
152
153TEST_F(VideoAdapterTest, AdaptZeroInterval) {
154 VideoFormat format = capturer_->GetSupportedFormats()->at(0);
155 format.interval = 0;
Per766ad3b2016-04-05 15:23:49 +0200156 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000157 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200158 for (int i = 0; i < 10; ++i)
159 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000160
161 // Verify no crash and that frames aren't dropped.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000162 VideoCapturerListener::Stats stats = listener_->GetStats();
163 EXPECT_GE(stats.captured_frames, 10);
164 EXPECT_EQ(0, stats.dropped_frames);
magjed709f73c2016-05-13 10:26:00 -0700165 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height,
166 capture_format_.width, capture_format_.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000167}
168
169// Adapt the frame rate to be half of the capture rate at the beginning. Expect
170// the number of dropped frames to be half of the number the captured frames.
magjed604abe02016-05-19 06:05:40 -0700171TEST_F(VideoAdapterTest, AdaptFramerateToHalf) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000172 VideoFormat request_format = capture_format_;
173 request_format.interval *= 2;
Per766ad3b2016-04-05 15:23:49 +0200174 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000175 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
magjed604abe02016-05-19 06:05:40 -0700176
177 // Capture 10 frames and verify that every other frame is dropped. The first
178 // frame should not be dropped.
179 capturer_->CaptureFrame();
180 EXPECT_GE(listener_->GetStats().captured_frames, 1);
181 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
182
183 capturer_->CaptureFrame();
184 EXPECT_GE(listener_->GetStats().captured_frames, 2);
nissef5297a02016-09-30 01:34:27 -0700185 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700186
187 capturer_->CaptureFrame();
188 EXPECT_GE(listener_->GetStats().captured_frames, 3);
189 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
190
191 capturer_->CaptureFrame();
192 EXPECT_GE(listener_->GetStats().captured_frames, 4);
nissef5297a02016-09-30 01:34:27 -0700193 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700194
195 capturer_->CaptureFrame();
196 EXPECT_GE(listener_->GetStats().captured_frames, 5);
197 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
198
199 capturer_->CaptureFrame();
200 EXPECT_GE(listener_->GetStats().captured_frames, 6);
nissef5297a02016-09-30 01:34:27 -0700201 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700202
203 capturer_->CaptureFrame();
204 EXPECT_GE(listener_->GetStats().captured_frames, 7);
205 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
206
207 capturer_->CaptureFrame();
208 EXPECT_GE(listener_->GetStats().captured_frames, 8);
nissef5297a02016-09-30 01:34:27 -0700209 EXPECT_EQ(4, listener_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700210
211 capturer_->CaptureFrame();
212 EXPECT_GE(listener_->GetStats().captured_frames, 9);
213 EXPECT_EQ(4, listener_->GetStats().dropped_frames);
214
215 capturer_->CaptureFrame();
216 EXPECT_GE(listener_->GetStats().captured_frames, 10);
nissef5297a02016-09-30 01:34:27 -0700217 EXPECT_EQ(5, listener_->GetStats().dropped_frames);
magjed604abe02016-05-19 06:05:40 -0700218}
219
220// Adapt the frame rate to be two thirds of the capture rate at the beginning.
221// Expect the number of dropped frames to be one thirds of the number the
222// captured frames.
223TEST_F(VideoAdapterTest, AdaptFramerateToTwoThirds) {
224 VideoFormat request_format = capture_format_;
225 request_format.interval = request_format.interval * 3 / 2;
226 adapter_.OnOutputFormatRequest(request_format);
227 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
228
229 // Capture 10 frames and verify that every third frame is dropped. The first
230 // frame should not be dropped.
231 capturer_->CaptureFrame();
232 EXPECT_GE(listener_->GetStats().captured_frames, 1);
233 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
234
235 capturer_->CaptureFrame();
236 EXPECT_GE(listener_->GetStats().captured_frames, 2);
237 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
238
239 capturer_->CaptureFrame();
240 EXPECT_GE(listener_->GetStats().captured_frames, 3);
241 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
242
243 capturer_->CaptureFrame();
244 EXPECT_GE(listener_->GetStats().captured_frames, 4);
245 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
246
247 capturer_->CaptureFrame();
248 EXPECT_GE(listener_->GetStats().captured_frames, 5);
249 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
250
251 capturer_->CaptureFrame();
252 EXPECT_GE(listener_->GetStats().captured_frames, 6);
253 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
254
255 capturer_->CaptureFrame();
256 EXPECT_GE(listener_->GetStats().captured_frames, 7);
257 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
258
259 capturer_->CaptureFrame();
260 EXPECT_GE(listener_->GetStats().captured_frames, 8);
261 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
262
263 capturer_->CaptureFrame();
264 EXPECT_GE(listener_->GetStats().captured_frames, 9);
265 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
266
267 capturer_->CaptureFrame();
268 EXPECT_GE(listener_->GetStats().captured_frames, 10);
269 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
270}
271
272// Request frame rate twice as high as captured frame rate. Expect no frame
273// drop.
274TEST_F(VideoAdapterTest, AdaptFramerateHighLimit) {
275 VideoFormat request_format = capture_format_;
276 request_format.interval /= 2;
277 adapter_.OnOutputFormatRequest(request_format);
278 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200279 for (int i = 0; i < 10; ++i)
280 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000281
magjed604abe02016-05-19 06:05:40 -0700282 // Verify no frame drop.
283 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000284}
285
magjed604abe02016-05-19 06:05:40 -0700286// After the first timestamp, add a big offset to the timestamps. Expect that
287// the adapter is conservative and resets to the new offset and does not drop
288// any frame.
289TEST_F(VideoAdapterTest, AdaptFramerateTimestampOffset) {
290 const int64_t capture_interval = VideoFormat::FpsToInterval(30);
291 adapter_.OnOutputFormatRequest(
292 VideoFormat(640, 480, capture_interval, cricket::FOURCC_ANY));
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000293
magjed604abe02016-05-19 06:05:40 -0700294 const int64_t first_timestamp = 0;
295 adapter_.AdaptFrameResolution(640, 480, first_timestamp,
296 &cropped_width_, &cropped_height_,
297 &out_width_, &out_height_);
298 EXPECT_GT(out_width_, 0);
299 EXPECT_GT(out_height_, 0);
300
301 const int64_t big_offset = -987654321LL * 1000;
302 const int64_t second_timestamp = big_offset;
303 adapter_.AdaptFrameResolution(640, 480, second_timestamp,
304 &cropped_width_, &cropped_height_,
305 &out_width_, &out_height_);
306 EXPECT_GT(out_width_, 0);
307 EXPECT_GT(out_height_, 0);
308
309 const int64_t third_timestamp = big_offset + capture_interval;
310 adapter_.AdaptFrameResolution(640, 480, third_timestamp,
311 &cropped_width_, &cropped_height_,
312 &out_width_, &out_height_);
313 EXPECT_GT(out_width_, 0);
314 EXPECT_GT(out_height_, 0);
315}
316
317// Request 30 fps and send 30 fps with jitter. Expect that no frame is dropped.
318TEST_F(VideoAdapterTest, AdaptFramerateTimestampJitter) {
319 const int64_t capture_interval = VideoFormat::FpsToInterval(30);
320 adapter_.OnOutputFormatRequest(
321 VideoFormat(640, 480, capture_interval, cricket::FOURCC_ANY));
322
323 adapter_.AdaptFrameResolution(640, 480, capture_interval * 0 / 10,
324 &cropped_width_, &cropped_height_,
325 &out_width_, &out_height_);
326 EXPECT_GT(out_width_, 0);
327 EXPECT_GT(out_height_, 0);
328
329 adapter_.AdaptFrameResolution(640, 480, capture_interval * 10 / 10 - 1,
330 &cropped_width_, &cropped_height_,
331 &out_width_, &out_height_);
332 EXPECT_GT(out_width_, 0);
333 EXPECT_GT(out_height_, 0);
334
335 adapter_.AdaptFrameResolution(640, 480, capture_interval * 25 / 10,
336 &cropped_width_, &cropped_height_,
337 &out_width_, &out_height_);
338 EXPECT_GT(out_width_, 0);
339 EXPECT_GT(out_height_, 0);
340
341 adapter_.AdaptFrameResolution(640, 480, capture_interval * 30 / 10,
342 &cropped_width_, &cropped_height_,
343 &out_width_, &out_height_);
344 EXPECT_GT(out_width_, 0);
345 EXPECT_GT(out_height_, 0);
346
347 adapter_.AdaptFrameResolution(640, 480, capture_interval * 35 / 10,
348 &cropped_width_, &cropped_height_,
349 &out_width_, &out_height_);
350 EXPECT_GT(out_width_, 0);
351 EXPECT_GT(out_height_, 0);
352
353 adapter_.AdaptFrameResolution(640, 480, capture_interval * 50 / 10,
354 &cropped_width_, &cropped_height_,
355 &out_width_, &out_height_);
356 EXPECT_GT(out_width_, 0);
357 EXPECT_GT(out_height_, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000358}
359
360// Adapt the frame rate to be half of the capture rate after capturing no less
361// than 10 frames. Expect no frame dropped before adaptation and frame dropped
362// after adaptation.
363TEST_F(VideoAdapterTest, AdaptFramerateOntheFly) {
364 VideoFormat request_format = capture_format_;
Per766ad3b2016-04-05 15:23:49 +0200365 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000366 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200367 for (int i = 0; i < 10; ++i)
368 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000369
370 // Verify no frame drop before adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000371 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000372
373 // Adapat the frame rate.
374 request_format.interval *= 2;
Per766ad3b2016-04-05 15:23:49 +0200375 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000376
Magnus Jedvert01840572015-04-10 11:18:39 +0200377 for (int i = 0; i < 20; ++i)
378 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000379
380 // Verify frame drop after adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000381 EXPECT_GT(listener_->GetStats().dropped_frames, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000382}
383
magjed709f73c2016-05-13 10:26:00 -0700384// Set a very high output pixel resolution. Expect no cropping or resolution
385// change.
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000386TEST_F(VideoAdapterTest, AdaptFrameResolutionHighLimit) {
Per766ad3b2016-04-05 15:23:49 +0200387 VideoFormat output_format = capture_format_;
magjed709f73c2016-05-13 10:26:00 -0700388 output_format.width *= 10;
389 output_format.height *= 10;
Per766ad3b2016-04-05 15:23:49 +0200390 adapter_.OnOutputFormatRequest(output_format);
nisse47ac4622016-05-25 08:47:01 -0700391 EXPECT_TRUE(adapter_.AdaptFrameResolution(
392 capture_format_.width, capture_format_.height, 0,
393 &cropped_width_, &cropped_height_,
394 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700395 EXPECT_EQ(capture_format_.width, cropped_width_);
396 EXPECT_EQ(capture_format_.height, cropped_height_);
397 EXPECT_EQ(capture_format_.width, out_width_);
398 EXPECT_EQ(capture_format_.height, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000399}
400
401// Adapt the frame resolution to be the same as capture resolution. Expect no
magjed709f73c2016-05-13 10:26:00 -0700402// cropping or resolution change.
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000403TEST_F(VideoAdapterTest, AdaptFrameResolutionIdentical) {
Per766ad3b2016-04-05 15:23:49 +0200404 adapter_.OnOutputFormatRequest(capture_format_);
nisse47ac4622016-05-25 08:47:01 -0700405 EXPECT_TRUE(adapter_.AdaptFrameResolution(
406 capture_format_.width, capture_format_.height, 0,
407 &cropped_width_, &cropped_height_,
408 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700409 EXPECT_EQ(capture_format_.width, cropped_width_);
410 EXPECT_EQ(capture_format_.height, cropped_height_);
411 EXPECT_EQ(capture_format_.width, out_width_);
412 EXPECT_EQ(capture_format_.height, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000413}
414
415// Adapt the frame resolution to be a quarter of the capture resolution. Expect
magjed709f73c2016-05-13 10:26:00 -0700416// no cropping, but a resolution change.
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000417TEST_F(VideoAdapterTest, AdaptFrameResolutionQuarter) {
418 VideoFormat request_format = capture_format_;
419 request_format.width /= 2;
420 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200421 adapter_.OnOutputFormatRequest(request_format);
nisse47ac4622016-05-25 08:47:01 -0700422 EXPECT_TRUE(adapter_.AdaptFrameResolution(
423 capture_format_.width, capture_format_.height, 0,
424 &cropped_width_, &cropped_height_,
425 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700426 EXPECT_EQ(capture_format_.width, cropped_width_);
427 EXPECT_EQ(capture_format_.height, cropped_height_);
428 EXPECT_EQ(request_format.width, out_width_);
429 EXPECT_EQ(request_format.height, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000430}
431
432// Adapt the pixel resolution to 0. Expect frame drop.
433TEST_F(VideoAdapterTest, AdaptFrameResolutionDrop) {
Per766ad3b2016-04-05 15:23:49 +0200434 VideoFormat output_format = capture_format_;
435 output_format.width = 0;
436 output_format.height = 0;
437 adapter_.OnOutputFormatRequest(output_format);
nisse47ac4622016-05-25 08:47:01 -0700438 EXPECT_FALSE(adapter_.AdaptFrameResolution(
439 capture_format_.width, capture_format_.height, 0,
440 &cropped_width_, &cropped_height_,
441 &out_width_, &out_height_));
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000442}
443
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000444// Adapt the frame resolution to be a quarter of the capture resolution at the
magjed709f73c2016-05-13 10:26:00 -0700445// beginning. Expect no cropping but a resolution change.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000446TEST_F(VideoAdapterTest, AdaptResolution) {
447 VideoFormat request_format = capture_format_;
448 request_format.width /= 2;
449 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200450 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000451 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200452 for (int i = 0; i < 10; ++i)
453 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000454
magjed709f73c2016-05-13 10:26:00 -0700455 // Verify no frame drop, no cropping, and resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000456 VideoCapturerListener::Stats stats = listener_->GetStats();
457 EXPECT_EQ(0, stats.dropped_frames);
magjed709f73c2016-05-13 10:26:00 -0700458 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height,
459 request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000460}
461
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000462// Adapt the frame resolution to be a quarter of the capture resolution after
463// capturing no less than 10 frames. Expect no resolution change before
464// adaptation and resolution change after adaptation.
465TEST_F(VideoAdapterTest, AdaptResolutionOnTheFly) {
466 VideoFormat request_format = capture_format_;
Per766ad3b2016-04-05 15:23:49 +0200467 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000468 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200469 for (int i = 0; i < 10; ++i)
470 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000471
472 // Verify no resolution change before adaptation.
magjed709f73c2016-05-13 10:26:00 -0700473 VerifyAdaptedResolution(listener_->GetStats(),
474 capture_format_.width, capture_format_.height,
475 request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000476
477 // Adapt the frame resolution.
478 request_format.width /= 2;
479 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200480 adapter_.OnOutputFormatRequest(request_format);
Magnus Jedvert01840572015-04-10 11:18:39 +0200481 for (int i = 0; i < 10; ++i)
482 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000483
484 // Verify resolution change after adaptation.
magjed709f73c2016-05-13 10:26:00 -0700485 VerifyAdaptedResolution(listener_->GetStats(),
486 capture_format_.width, capture_format_.height,
487 request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000488}
489
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000490// Drop all frames.
491TEST_F(VideoAdapterTest, DropAllFrames) {
492 VideoFormat format; // with resolution 0x0.
Per766ad3b2016-04-05 15:23:49 +0200493 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000494 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200495 for (int i = 0; i < 10; ++i)
496 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000497
498 // Verify all frames are dropped.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000499 VideoCapturerListener::Stats stats = listener_->GetStats();
500 EXPECT_GE(stats.captured_frames, 10);
501 EXPECT_EQ(stats.captured_frames, stats.dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000502}
503
Per766ad3b2016-04-05 15:23:49 +0200504TEST_F(VideoAdapterTest, TestOnOutputFormatRequest) {
magjed604abe02016-05-19 06:05:40 -0700505 VideoFormat format(640, 400, 0, 0);
nisse47ac4622016-05-25 08:47:01 -0700506 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
507 &cropped_width_, &cropped_height_,
508 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700509 EXPECT_EQ(640, cropped_width_);
510 EXPECT_EQ(400, cropped_height_);
511 EXPECT_EQ(640, out_width_);
512 EXPECT_EQ(400, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000513
Per766ad3b2016-04-05 15:23:49 +0200514 // Format request 640x400.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000515 format.height = 400;
Per766ad3b2016-04-05 15:23:49 +0200516 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700517 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
518 &cropped_width_, &cropped_height_,
519 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700520 EXPECT_EQ(640, cropped_width_);
521 EXPECT_EQ(400, cropped_height_);
522 EXPECT_EQ(640, out_width_);
523 EXPECT_EQ(400, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000524
magjed709f73c2016-05-13 10:26:00 -0700525 // Request 1280x720, higher than input, but aspect 16:9. Expect cropping but
526 // no scaling.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000527 format.width = 1280;
528 format.height = 720;
Per766ad3b2016-04-05 15:23:49 +0200529 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700530 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
531 &cropped_width_, &cropped_height_,
532 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700533 EXPECT_EQ(640, cropped_width_);
534 EXPECT_EQ(360, cropped_height_);
535 EXPECT_EQ(640, out_width_);
536 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000537
Per766ad3b2016-04-05 15:23:49 +0200538 // Request 0x0.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000539 format.width = 0;
540 format.height = 0;
Per766ad3b2016-04-05 15:23:49 +0200541 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700542 EXPECT_FALSE(adapter_.AdaptFrameResolution(640, 400, 0,
543 &cropped_width_, &cropped_height_,
544 &out_width_, &out_height_));
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000545
magjed709f73c2016-05-13 10:26:00 -0700546 // Request 320x200. Expect scaling, but no cropping.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000547 format.width = 320;
548 format.height = 200;
Per766ad3b2016-04-05 15:23:49 +0200549 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700550 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
551 &cropped_width_, &cropped_height_,
552 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700553 EXPECT_EQ(640, cropped_width_);
554 EXPECT_EQ(400, cropped_height_);
555 EXPECT_EQ(320, out_width_);
556 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000557
magjed709f73c2016-05-13 10:26:00 -0700558 // Request resolution close to 2/3 scale. Expect adapt down. Scaling to 2/3
559 // is not optimized and not allowed, therefore 1/2 scaling will be used
560 // instead.
561 format.width = 424;
562 format.height = 265;
Per766ad3b2016-04-05 15:23:49 +0200563 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700564 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
565 &cropped_width_, &cropped_height_,
566 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700567 EXPECT_EQ(640, cropped_width_);
568 EXPECT_EQ(400, cropped_height_);
569 EXPECT_EQ(320, out_width_);
570 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000571
Per766ad3b2016-04-05 15:23:49 +0200572 // Request resolution of 3 / 8. Expect adapt down.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000573 format.width = 640 * 3 / 8;
574 format.height = 400 * 3 / 8;
Per766ad3b2016-04-05 15:23:49 +0200575 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700576 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
577 &cropped_width_, &cropped_height_,
578 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700579 EXPECT_EQ(640, cropped_width_);
580 EXPECT_EQ(400, cropped_height_);
581 EXPECT_EQ(640 * 3 / 8, out_width_);
582 EXPECT_EQ(400 * 3 / 8, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000583
Per766ad3b2016-04-05 15:23:49 +0200584 // Switch back up. Expect adapt.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000585 format.width = 320;
586 format.height = 200;
Per766ad3b2016-04-05 15:23:49 +0200587 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700588 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
589 &cropped_width_, &cropped_height_,
590 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700591 EXPECT_EQ(640, cropped_width_);
592 EXPECT_EQ(400, cropped_height_);
593 EXPECT_EQ(320, out_width_);
594 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000595
Per766ad3b2016-04-05 15:23:49 +0200596 // Format request 480x300.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000597 format.width = 480;
598 format.height = 300;
Per766ad3b2016-04-05 15:23:49 +0200599 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700600 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
601 &cropped_width_, &cropped_height_,
602 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700603 EXPECT_EQ(640, cropped_width_);
604 EXPECT_EQ(400, cropped_height_);
605 EXPECT_EQ(480, out_width_);
606 EXPECT_EQ(300, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000607}
608
Per766ad3b2016-04-05 15:23:49 +0200609TEST_F(VideoAdapterTest, TestViewRequestPlusCameraSwitch) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000610 // Start at HD.
magjed604abe02016-05-19 06:05:40 -0700611 VideoFormat format(1280, 720, 0, 0);
nisse47ac4622016-05-25 08:47:01 -0700612 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
613 &cropped_width_, &cropped_height_,
614 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700615 EXPECT_EQ(1280, cropped_width_);
616 EXPECT_EQ(720, cropped_height_);
617 EXPECT_EQ(1280, out_width_);
618 EXPECT_EQ(720, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000619
Per766ad3b2016-04-05 15:23:49 +0200620 // Format request for VGA.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000621 format.width = 640;
622 format.height = 360;
Per766ad3b2016-04-05 15:23:49 +0200623 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700624 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
625 &cropped_width_, &cropped_height_,
626 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700627 EXPECT_EQ(1280, cropped_width_);
628 EXPECT_EQ(720, cropped_height_);
629 EXPECT_EQ(640, out_width_);
630 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000631
632 // Now, the camera reopens at VGA.
633 // Both the frame and the output format should be 640x360.
nisse47ac4622016-05-25 08:47:01 -0700634 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0,
635 &cropped_width_, &cropped_height_,
636 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700637 EXPECT_EQ(640, cropped_width_);
638 EXPECT_EQ(360, cropped_height_);
639 EXPECT_EQ(640, out_width_);
640 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000641
642 // And another view request comes in for 640x360, which should have no
643 // real impact.
Per766ad3b2016-04-05 15:23:49 +0200644 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700645 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0,
646 &cropped_width_, &cropped_height_,
647 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700648 EXPECT_EQ(640, cropped_width_);
649 EXPECT_EQ(360, cropped_height_);
650 EXPECT_EQ(640, out_width_);
651 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000652}
653
Per766ad3b2016-04-05 15:23:49 +0200654TEST_F(VideoAdapterTest, TestVGAWidth) {
655 // Reqeuested Output format is 640x360.
magjed604abe02016-05-19 06:05:40 -0700656 VideoFormat format(640, 360, 0, FOURCC_I420);
Per766ad3b2016-04-05 15:23:49 +0200657 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000658
nisse47ac4622016-05-25 08:47:01 -0700659 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
660 &cropped_width_, &cropped_height_,
661 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700662 // Expect cropping.
663 EXPECT_EQ(640, cropped_width_);
664 EXPECT_EQ(360, cropped_height_);
665 EXPECT_EQ(640, out_width_);
666 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000667
668 // But if frames come in at 640x360, we shouldn't adapt them down.
nisse47ac4622016-05-25 08:47:01 -0700669 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0,
670 &cropped_width_, &cropped_height_,
671 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700672 EXPECT_EQ(640, cropped_width_);
673 EXPECT_EQ(360, cropped_height_);
674 EXPECT_EQ(640, out_width_);
675 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000676
nisse47ac4622016-05-25 08:47:01 -0700677 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
678 &cropped_width_, &cropped_height_,
679 &out_width_, &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_);
Per766ad3b2016-04-05 15:23:49 +0200684}
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000685
Per766ad3b2016-04-05 15:23:49 +0200686TEST_F(VideoAdapterTest, TestOnResolutionRequestInSmallSteps) {
nisse47ac4622016-05-25 08:47:01 -0700687 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
688 &cropped_width_, &cropped_height_,
689 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700690 EXPECT_EQ(1280, cropped_width_);
691 EXPECT_EQ(720, cropped_height_);
692 EXPECT_EQ(1280, out_width_);
693 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200694
695 // Adapt down one step.
696 adapter_.OnResolutionRequest(rtc::Optional<int>(1280 * 720 - 1),
697 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700698 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
699 &cropped_width_, &cropped_height_,
700 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700701 EXPECT_EQ(1280, cropped_width_);
702 EXPECT_EQ(720, cropped_height_);
703 EXPECT_EQ(960, out_width_);
704 EXPECT_EQ(540, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200705
706 // Adapt down one step more.
707 adapter_.OnResolutionRequest(rtc::Optional<int>(960 * 540 - 1),
708 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700709 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
710 &cropped_width_, &cropped_height_,
711 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700712 EXPECT_EQ(1280, cropped_width_);
713 EXPECT_EQ(720, cropped_height_);
714 EXPECT_EQ(640, out_width_);
715 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200716
717 // Adapt down one step more.
718 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
719 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700720 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
721 &cropped_width_, &cropped_height_,
722 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700723 EXPECT_EQ(1280, cropped_width_);
724 EXPECT_EQ(720, cropped_height_);
725 EXPECT_EQ(480, out_width_);
726 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200727
728 // Adapt up one step.
729 adapter_.OnResolutionRequest(rtc::Optional<int>(),
730 rtc::Optional<int>(480 * 270));
nisse47ac4622016-05-25 08:47:01 -0700731 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
732 &cropped_width_, &cropped_height_,
733 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700734 EXPECT_EQ(1280, cropped_width_);
735 EXPECT_EQ(720, cropped_height_);
736 EXPECT_EQ(640, out_width_);
737 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200738
739 // Adapt up one step more.
740 adapter_.OnResolutionRequest(rtc::Optional<int>(),
741 rtc::Optional<int>(640 * 360));
nisse47ac4622016-05-25 08:47:01 -0700742 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
743 &cropped_width_, &cropped_height_,
744 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700745 EXPECT_EQ(1280, cropped_width_);
746 EXPECT_EQ(720, cropped_height_);
747 EXPECT_EQ(960, out_width_);
748 EXPECT_EQ(540, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200749
750 // Adapt up one step more.
751 adapter_.OnResolutionRequest(rtc::Optional<int>(),
752 rtc::Optional<int>(960 * 720));
nisse47ac4622016-05-25 08:47:01 -0700753 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
754 &cropped_width_, &cropped_height_,
755 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700756 EXPECT_EQ(1280, cropped_width_);
757 EXPECT_EQ(720, cropped_height_);
758 EXPECT_EQ(1280, out_width_);
759 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200760}
761
762TEST_F(VideoAdapterTest, TestOnResolutionRequestMaxZero) {
nisse47ac4622016-05-25 08:47:01 -0700763 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
764 &cropped_width_, &cropped_height_,
765 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700766 EXPECT_EQ(1280, cropped_width_);
767 EXPECT_EQ(720, cropped_height_);
768 EXPECT_EQ(1280, out_width_);
769 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200770
771 adapter_.OnResolutionRequest(rtc::Optional<int>(0), rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700772 EXPECT_FALSE(adapter_.AdaptFrameResolution(1280, 720, 0,
773 &cropped_width_, &cropped_height_,
774 &out_width_, &out_height_));
Per766ad3b2016-04-05 15:23:49 +0200775}
776
777TEST_F(VideoAdapterTest, TestOnResolutionRequestInLargeSteps) {
778 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
779 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700780 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
781 &cropped_width_, &cropped_height_,
782 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700783 EXPECT_EQ(1280, cropped_width_);
784 EXPECT_EQ(720, cropped_height_);
785 EXPECT_EQ(480, out_width_);
786 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200787
788 adapter_.OnResolutionRequest(rtc::Optional<int>(),
789 rtc::Optional<int>(960 * 720));
nisse47ac4622016-05-25 08:47:01 -0700790 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
791 &cropped_width_, &cropped_height_,
792 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700793 EXPECT_EQ(1280, cropped_width_);
794 EXPECT_EQ(720, cropped_height_);
795 EXPECT_EQ(1280, out_width_);
796 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200797}
798
799TEST_F(VideoAdapterTest, TestOnOutputFormatRequestCapsMaxResolution) {
800 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
801 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700802 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
803 &cropped_width_, &cropped_height_,
804 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700805 EXPECT_EQ(1280, cropped_width_);
806 EXPECT_EQ(720, cropped_height_);
807 EXPECT_EQ(480, out_width_);
808 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200809
magjed604abe02016-05-19 06:05:40 -0700810 VideoFormat new_format(640, 360, 0, FOURCC_I420);
Per766ad3b2016-04-05 15:23:49 +0200811 adapter_.OnOutputFormatRequest(new_format);
nisse47ac4622016-05-25 08:47:01 -0700812 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
813 &cropped_width_, &cropped_height_,
814 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700815 EXPECT_EQ(1280, cropped_width_);
816 EXPECT_EQ(720, cropped_height_);
817 EXPECT_EQ(480, out_width_);
818 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200819
820 adapter_.OnResolutionRequest(rtc::Optional<int>(),
821 rtc::Optional<int>(960 * 720));
nisse47ac4622016-05-25 08:47:01 -0700822 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
823 &cropped_width_, &cropped_height_,
824 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700825 EXPECT_EQ(1280, cropped_width_);
826 EXPECT_EQ(720, cropped_height_);
827 EXPECT_EQ(640, out_width_);
828 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000829}
830
Per766ad3b2016-04-05 15:23:49 +0200831TEST_F(VideoAdapterTest, TestOnResolutionRequestReset) {
nisse47ac4622016-05-25 08:47:01 -0700832 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
833 &cropped_width_, &cropped_height_,
834 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700835 EXPECT_EQ(1280, cropped_width_);
836 EXPECT_EQ(720, cropped_height_);
837 EXPECT_EQ(1280, out_width_);
838 EXPECT_EQ(720, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000839
Per766ad3b2016-04-05 15:23:49 +0200840 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
841 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700842 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
843 &cropped_width_, &cropped_height_,
844 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700845 EXPECT_EQ(1280, cropped_width_);
846 EXPECT_EQ(720, cropped_height_);
847 EXPECT_EQ(480, out_width_);
848 EXPECT_EQ(270, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000849
Per766ad3b2016-04-05 15:23:49 +0200850 adapter_.OnResolutionRequest(rtc::Optional<int>(), rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700851 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
852 &cropped_width_, &cropped_height_,
853 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700854 EXPECT_EQ(1280, cropped_width_);
855 EXPECT_EQ(720, cropped_height_);
856 EXPECT_EQ(1280, out_width_);
857 EXPECT_EQ(720, out_height_);
858}
859
860TEST_F(VideoAdapterTest, TestCroppingWithResolutionRequest) {
861 // Ask for 640x360 (16:9 aspect).
magjed604abe02016-05-19 06:05:40 -0700862 adapter_.OnOutputFormatRequest(VideoFormat(640, 360, 0, FOURCC_I420));
magjed709f73c2016-05-13 10:26:00 -0700863 // Send 640x480 (4:3 aspect).
nisse47ac4622016-05-25 08:47:01 -0700864 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
865 &cropped_width_, &cropped_height_,
866 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700867 // Expect cropping to 16:9 format and no scaling.
868 EXPECT_EQ(640, cropped_width_);
869 EXPECT_EQ(360, cropped_height_);
870 EXPECT_EQ(640, out_width_);
871 EXPECT_EQ(360, out_height_);
872
873 // Adapt down one step.
874 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
875 rtc::Optional<int>());
876 // Expect cropping to 16:9 format and 3/4 scaling.
nisse47ac4622016-05-25 08:47:01 -0700877 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
878 &cropped_width_, &cropped_height_,
879 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700880 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 down one step more.
886 adapter_.OnResolutionRequest(rtc::Optional<int>(480 * 270 - 1),
887 rtc::Optional<int>());
888 // Expect cropping to 16:9 format and 1/2 scaling.
nisse47ac4622016-05-25 08:47:01 -0700889 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
890 &cropped_width_, &cropped_height_,
891 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700892 EXPECT_EQ(640, cropped_width_);
893 EXPECT_EQ(360, cropped_height_);
894 EXPECT_EQ(320, out_width_);
895 EXPECT_EQ(180, out_height_);
896
897 // Adapt up one step.
898 adapter_.OnResolutionRequest(rtc::Optional<int>(),
899 rtc::Optional<int>(320 * 180));
900 // Expect cropping to 16:9 format and 3/4 scaling.
nisse47ac4622016-05-25 08:47:01 -0700901 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
902 &cropped_width_, &cropped_height_,
903 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700904 EXPECT_EQ(640, cropped_width_);
905 EXPECT_EQ(360, cropped_height_);
906 EXPECT_EQ(480, out_width_);
907 EXPECT_EQ(270, out_height_);
908
909 // Adapt up one step more.
910 adapter_.OnResolutionRequest(rtc::Optional<int>(),
911 rtc::Optional<int>(480 * 270));
912 // Expect cropping to 16:9 format and no scaling.
nisse47ac4622016-05-25 08:47:01 -0700913 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
914 &cropped_width_, &cropped_height_,
915 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700916 EXPECT_EQ(640, cropped_width_);
917 EXPECT_EQ(360, cropped_height_);
918 EXPECT_EQ(640, out_width_);
919 EXPECT_EQ(360, out_height_);
920
921 // Try to adapt up one step more.
922 adapter_.OnResolutionRequest(rtc::Optional<int>(),
923 rtc::Optional<int>(640 * 360));
924 // Expect cropping to 16:9 format and no scaling.
nisse47ac4622016-05-25 08:47:01 -0700925 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
926 &cropped_width_, &cropped_height_,
927 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700928 EXPECT_EQ(640, cropped_width_);
929 EXPECT_EQ(360, cropped_height_);
930 EXPECT_EQ(640, out_width_);
931 EXPECT_EQ(360, out_height_);
932}
933
934TEST_F(VideoAdapterTest, TestCroppingOddResolution) {
935 // Ask for 640x360 (16:9 aspect), with 3/16 scaling.
magjed709f73c2016-05-13 10:26:00 -0700936 adapter_.OnOutputFormatRequest(
magjed604abe02016-05-19 06:05:40 -0700937 VideoFormat(640, 360, 0, FOURCC_I420));
magjed709f73c2016-05-13 10:26:00 -0700938 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 * 3 / 16 * 3 / 16),
939 rtc::Optional<int>());
940
941 // Send 640x480 (4:3 aspect).
nisse47ac4622016-05-25 08:47:01 -0700942 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
943 &cropped_width_, &cropped_height_,
944 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700945
946 // Instead of getting the exact aspect ratio with cropped resolution 640x360,
947 // the resolution should be adjusted to get a perfect scale factor instead.
948 EXPECT_EQ(640, cropped_width_);
949 EXPECT_EQ(368, cropped_height_);
950 EXPECT_EQ(120, out_width_);
951 EXPECT_EQ(69, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000952}
953
954} // namespace cricket